[英]How can I parameterize Mixins in python, without calling their constructor explicitly?
我想在 python 中更多地使用 Mixins 並且喜歡以下模式:
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!"
但是我還沒有解決參數化mixin的問題。 在我的工作中,我看到很多對超類的顯式__init__
調用 alá
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
之外的每個類都是如此,它始終是任何繼承層次結構中的根類。
對於你的例子
class A(B, FloorMixin):
def __init__(self, desk, chair, floor):
B.__init__(self, desk, chair)
FloorMixin.__init__(floor)
這意味着A
、 B
和FloorMixin
都應該調用super().__init__
,並且在實例化A
時應該使用關鍵字參數,以便沒有基於排序的沖突。
class B:
def __init__(self, desk, chair, **kwargs):
super().__init__(**kwargs)
# Do stuff with desk and chair
class FloorMixin:
def __init__(self, floor, **kwargs):
super().__init__(**kwargs)
# Do stuff with floor
class A(B, FloorMixin):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# If there's nothing else to do, you don't
# even need to define A.__init__
# With keyword arguments, order doesn't matter
# Each __init__ will find the arguments it needs
# and pass on the rest
a = A(floor="...", chair="...", desk="...")
A
的方法解析順序是[A, B, FloorMixin, object]
,因此每次調用super().__init__
__init__
從行中的下一個類調用__init__
。 A.__init__
調用B.__init__
,后者調用FloorMixin.__init__
,后者調用object.__init__
。 重要的是,請注意,這意味着在運行時, B.__init__
調用B
的作者甚至可能不知道的類的__init__
。 這就是為什么接受意外的關鍵字參數並傳遞它們很重要的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.