我想在python中更多地使用mixin,比如:
class Person:
[...]
class Greetable:
greeting: str
def __init__(*args, **kwargs):
super().__init(*args, **kwargs)
... greeting related setup
def greet(self):
print(f"{self.greeting} sir or madam!")
class Sailor(Greetable, Person):
def __init__(self):
super().__init__()
self.greeting = "Ahoy"
>>> Sailor().greet()
"Ahoy sir or madam!"
但我还没有解决参数化混合的问题。在我的工作中,我看到很多对超类的显式__init__
调用á
class A(B, FloorMixin):
def __init__(desk, chair, floor):
B.__init__(self, desk, chair)
FloorMixin.__init__(floor)
我看到了分解参数并显式分发它们的用法,但是我希望保留上述Mixin示例的__init__
所具有的“passthrough”属性
我只能考虑将Mixin的所有参数作为特定的关键字参数,这些参数从**kwargs
参数中得到pop
,或者只依赖Mixin中存在的字段,并且必须在之前设置它们,这将把最后一个示例变成:
class A(FloorMixin, B):
def __init__(desk, chair, floor):
self._floor = floor # FloorMixin expects a _floor attribute
super().__init__(desk, chair)
正确使用
super
的关键是,层次结构中涉及的每个类都应该假定其他所有类也将调用super
。除了object
之外的所有类都是这样,它总是任何继承层次结构中的根类以你为例
这意味着
A
、B
和FloorMixin
都应该调用super().__init__
,并且在实例化A
时应该使用关键字参数,以便不存在基于顺序的冲突A
的方法解析顺序是[A, B, FloorMixin, object]
,因此对super().__init__
的每个调用都从行中的下一个类调用__init__
A.__init__
调用B.__init__
,后者调用FloorMixin.__init__
,后者调用object.__init__
。重要的是,请注意,这意味着在运行时,B.__init__
调用一个类的__init__
,而B
的作者可能根本不知道这个类。这就是为什么重要的是接受意外的关键字参数并传递它们相关问题 更多 >
编程相关推荐