[英]How to: safely call super constructors with different arguments
我已經看到super().__init__(*args)
用於安全地調用超級構造函數(以一種不會失敗菱形繼承的方式)。 但是我找不到以這種方式調用具有不同 arguments 的不同超級構造函數的方法。
這是一個說明問題的示例。
from typing import TypeVar, Generic
X = TypeVar("X")
Y = TypeVar("Y")
class Base:
def __init__(self):
pass
class Left(Base, Generic[X]):
def __init__(self, x:X):
super().__init__()
self.lft = x
class TopRight(Base, Generic[Y]):
def __init__(self, y:Y):
super().__init__()
self.rgh = y
class BottomRight(TopRight[Y], Generic[Y]):
def __init__(self, y:Y):
super().__init__(y + y)
class Root(Left[X], BottomRight[Y], Generic[X, Y]):
def __init__(self, x:X, y:Y):
pass #issue here
#does not work
#super().__init__(x)
#super().__init__(y)
#calls base twice
#Left[X].__init__(x)
#BottomRight[Y].__init__(y)
如何分別安全地調用Left.__init__(x)
和BottomRight.__init__(y)
?
問題是,要以合作形式使用,中間類必須接受不“針對”它們的 arguments,並以透明的方式將它們傳遞給自己的super
調用。
你他們不會多次調用你的祖先類:你讓語言運行時為你做這件事。
你的代碼應該寫成:
from typing import Generic, TypeVar
X = TypeVar("X")
Y = TypeVar("Y")
class Base:
def __init__(self):
pass
class Left(Base, Generic[X]):
def __init__(self, x:X, **kwargs):
super().__init__(**kwargs)
self.lft = x
class TopRight(Base, Generic[Y]):
def __init__(self, y:Y, **kwargs):
super().__init__(**kwargs)
self.rgh = y
class BottomRight(TopRight[Y], Generic[Y]):
def __init__(self, y:Y, **kwargs): # <- when this is executed, "y" is extracted from kwargs
super().__init__(y=y + y, **kwargs) # <- "x" remains in kwargs, but this class does not have to care about it.
class Root(Left[X], BottomRight[Y], Generic[X, Y]):
def __init__(self, x:X, y:Y):
super().__init__(x=x, y=y) # <- will traverse all superclasses, "Generic" being last
另外,請注意,根據項目的目的和最終的復雜性,這些類型注釋可能一無所獲,反而會增加代碼的復雜性,否則會變得微不足道。 它們並不總是在 Python 項目中有所收獲,盡管由於工具(即 IDE)的情況,可能會推薦它們。
Also, check this similar answer from a few days ago, were I detail a bit more of Python method resolution order mechanisms, and point to the official documentation on them: In multiple inheritance in Python, init of parent class A and B is done at同時?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.