假设我有一个库,如下所示,其中Person是一个面向用户的类。
class SwissArmyKnife:
def open_bottle(self):
"""...etc...."""
def open_package_with_scissors(self):
"""...etc...."""
def uncork_wine(self):
"""...etc...."""
def whittle_an_intricate_dolphin_figurine(self):
"""...etc...."""
class Person:
def __init__(self):
self.swiss_army_knife = SwissArmyKnife()
def open_bottle(self):
self.swiss_army_knife.open_bottle()
def open_package_with_scissors(self):
self.swiss_army_knife.open_package_with_scissors()
def uncork_wine(self):
self.swiss_army_knife.uncork_wine()
def whittle_an_intricate_dolphin_figurine(self):
self.swiss_army_knife.whittle_an_intricate_dolphin_figurine()我想将SwissArmyKnife的所有方法传递给Person,因为Person将有一个SwissArmyKnife,但理想情况下,我希望避免Person类中的所有样板代码,因为每次我更新瑞士军刀所能做的事情时,我也必须记住更新person类。
这样做的一种方法是让Person继承SwissArmyKnife,但这感觉很尴尬,因为一个人不是瑞士军刀,他们只是有一把刀。
另一种可能只是期望用户编写person.swiss_army_knife.open_bottle(),但这有点冗长。另外,在导致我提出这个玩具问题的实际案例中,我已经发布了一个库的版本,您可以只编写person.open_bottle(),我不想破坏向后兼容性。
有什么好的方法不让我看到自动检查SwissArmyKnife到Person的方法吗?你要做什么呢?
发布于 2022-07-04 23:53:48
如果对使用继承的反对意见似乎在语义上令人困惑,那么您可以考虑使用混合模式。在Python中使用Mixins的方式仍然使用继承,但是这种模式传达的是“具有”的功能而不是“是一个”的关系。
这个StackOverflow问题对这个主题进行了很好的讨论。
发布于 2022-07-03 05:33:40
如果您真的、真的、真的想这样做,您可以重载特殊的__getattr__方法。根据文档的说法
当默认属性访问与
__getattr__一起失败时调用AttributeError (__getattribute__()引发AttributeError,因为名称不是类树中的实例属性或属性;或者名称属性的__get__()引发AttributeError).`
因此,您可以自动将任何未定义的方法调用转发给瑞士军刀,如下所示:
class SwissArmyKnife:
def doit(self):
print("I done it!")
class Person:
def __init__(self):
self.swiss_army_knife = SwissArmyKnife()
def say_howdy(self):
print("howdy")
def __getattr__(self, name):
return getattr(self.swiss_army_knife, name)
p = Person()
p.say_howdy()
p.doit()<script src="https://cdn.jsdelivr.net/gh/pysnippet/pysnippet@latest/snippet.min.js"></script>
https://stackoverflow.com/questions/72843876
复制相似问题