如何编写Python类C,根据传入的Storage调用对应打印方法?
嘿,你的这个需求很常见,但你设想的那种用@storage=storageA这类装饰器的写法在Python里是行不通的——Python没有这种语法的装饰器哦。不过我们有好几种靠谱的方式能实现你想要的效果:让类C根据传入的storage类型自动调用对应的方法,我给你梳理几个常用方案:
方案一:初始化时绑定对应方法(最直接)
这种方式在类C初始化时,就根据传入的storage类型,把对应的方法绑定到一个统一的接口上,外部调用时只需要用这个统一接口就行,不用关心内部逻辑。
class A: def print_abc(self): print('abc') class B: def print_def(self): print('def') # 先创建A和B的实例,对应你的storageA和storageB storageA = A() storageB = B() class C: def __init__(self, storage): self.storage = storage # 根据storage类型绑定对应的方法 if isinstance(storage, A): self.print_content = self.storage.print_abc elif isinstance(storage, B): self.print_content = self.storage.print_def else: raise ValueError("不支持的storage类型,请传入A或B的实例") # 测试效果 c_for_a = C(storageA) c_for_a.print_content() # 输出: abc c_for_b = C(storageB) c_for_b.print_content() # 输出: def
这种方案的优势是代码简单易懂,外部使用时不用区分storage类型,只需要调用统一的print_content方法即可。
方案二:用__getattr__动态匹配方法
如果你希望外部还是能直接调用print_abc或print_def这类方法,同时确保只有对应storage类型的实例才能调用,可以用Python的__getattr__魔术方法,在调用方法时动态判断并返回对应的方法。
class C: def __init__(self, storage): self.storage = storage def __getattr__(self, name): # 当调用print_abc时,检查是否是A的实例 if name == 'print_abc' and isinstance(self.storage, A): return self.storage.print_abc # 当调用print_def时,检查是否是B的实例 elif name == 'print_def' and isinstance(self.storage, B): return self.storage.print_def # 不匹配时抛出标准的属性错误 raise AttributeError(f"'C' object has no attribute '{name}'") # 测试效果 c_for_a = C(storageA) c_for_a.print_abc() # 输出: abc # c_for_a.print_def() # 会抛出AttributeError,因为storageA是A的实例 c_for_b = C(storageB) c_for_b.print_def() # 输出: def # c_for_b.print_abc() # 会抛出AttributeError
这种方案更灵活,只有在实际调用方法时才会做类型检查,但外部调用时需要对应好storage的方法,否则会报错。
方案三:策略模式(适合未来扩展)
如果以后可能会新增更多的storage类型,策略模式会是更优雅的选择——把每个storage类型对应的方法映射成策略,类C只负责根据策略调用对应方法,符合开闭原则(新增类型不用修改C类代码)。
# 定义策略字典:key是storage类,value是对应的方法名 STORAGE_STRATEGIES = { A: 'print_abc', B: 'print_def' } class C: def __init__(self, storage): self.storage = storage storage_type = type(storage) if storage_type not in STORAGE_STRATEGIES: raise ValueError(f"不支持的storage类型: {storage_type}") self.target_method = STORAGE_STRATEGIES[storage_type] def print_content(self): # 通过getattr调用对应的方法 getattr(self.storage, self.target_method)() # 测试效果 c_for_a = C(storageA) c_for_a.print_content() # 输出: abc c_for_b = C(storageB) c_for_b.print_content() # 输出: def
以后新增比如类D和对应的storageD时,只需要在STORAGE_STRATEGIES里加一行D: 'print_ghi'就行,完全不用修改C类的逻辑。
内容的提问来源于stack exchange,提问作者Alem
相关产品推荐
相关产品推荐

