我到处看,每个人都在说超级()有多棒。但是,我倾向于不使用super(),因为它使一切都比我想要的要复杂得多。我见过一些使用super()的流行示例,但它们似乎从未显示将位置所需的参数传递到基类构造函数中。
我知道Python中的菱形问题,而super()阻止了两次调用base_base类。(在本个案中属A类)
A类的构造函数会被调用两次吗?(即案件2)
下面是我对这两种情况的代码。
案例1:使用._ init _()
#abstractclass
class A(object):
#abstractmethod
def __init__(self, for_a, *args):
self.val_a = for_a
#abstractclass
class B(A):
#abstractmethod
def __init__(self, for_a, for_b, for_c):
super().__init__(for_a, for_c)
self.val_b = for_b
#abstractclass
class C(A):
#abstractmethod
def __init__(self, for_a, for_c):
super().__init__(for_a)
self.val_c = for_c
class D(B, C):
def __init__(self, for_a, for_b, for_c, for_d):
super().__init__(for_a, for_b, for_c)
self.val_d = for_d
class E(B):
def __init__(self, for_a, for_b, for_e, *args):
super().__init__(for_a, for_b, *args)
self.val_e = for_e
newobject1 = D(1, 2, 3, 4)
newobject2 = E(10, 11, 12, 0)
案例2:静态-使用base._ init _(self)
#abstractclass
class A(object):
#abstractmethod
def __init__(self, for_a):
self.val_a = for_a
#abstractclass
class B(A):
#abstractmethod
def __init__(self, for_a, for_b):
A.__init__(self, for_a)
self.val_b = for_b
#abstractclass
class C(A):
#abstractmethod
def __init__(self, for_a, for_c):
A.__init__(self, for_a)
self.val_c = for_c
class D(B, C):
def __init__(self, for_a, for_b, for_c, for_d):
B.__init__(self, for_a, for_b)
C.__init__(self, for_a, for_c)
self.val_d = for_d
class E(B):
def __init__(self, for_a, for_b, for_e):
super().__init__(for_a, for_b)
self.val_e = for_e
newobject1 = D(1, 2, 3, 4)
newobject2 = E(10, 11, 12)
发布于 2016-03-08 13:07:37
A类的构造函数会被调用两次吗?
当然,如果构造函数是缓慢的,或者是非幂等的,或者如果它获得资源,如文件句柄或数据库连接。在更复杂的继承结构中,您还可能会得到调用4次或6次的构造函数,或者从子继承图到祖先的继承图上的路径数。
我倾向于不使用超级(),因为它使一切比我想要的要复杂得多
这不是让事情变得复杂的super
--而是多重继承。在多重继承中避免super
只会给您带来不同的、可能比super
的问题更糟糕的问题。
我见过一些使用super()的流行示例,但它们似乎从未显示将位置所需的参数传递到基类构造函数中。
这是因为位置构造函数参数在多重继承中不能很好地工作。如果您想要使用这样的多继承结构,请尝试只使用参数关键字,并使用**kwargs
传递其他类要处理的不可识别的参数。“Python的超级()被认为是超级”对如何使其工作有一些很好的建议。
发布于 2016-03-08 13:15:53
super()
的思想是支持方法分解顺序,这样您就可以使用合作继承编写程序。
如果您想调用超类的方法,合作继承是有意义的,但是您不知道具体的超类是什么--您只有一个假设,即该方法具有与您正在编写的方法相同的签名。
在您的示例中,每个__init__
都是不同的,因此对于协作继承来说,这不是一个好的用例。每个类实际上都需要知道super
的目标是什么,以便正确地调用它。因此,在这里您并没有从super
中得到太多的好处。
让我们不要忘记:多重继承会导致混乱。为了让您的代码可以理解,并控制意大利面,您可以遵守一些约定(一系列限制)。一种方法是使用一些基类作为混合器。另一个想法是合作继承。Python有像super
这样的语言构造来支持这些,但是如果您可以自由地走出这些边界。这与它自己的一系列问题有关。
https://stackoverflow.com/questions/35877911
复制