首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用超级vs静态调用基类的Python

使用超级vs静态调用基类的Python
EN

Stack Overflow用户
提问于 2016-03-08 21:00:36
回答 2查看 1K关注 0票数 1

我到处看,每个人都在说超级()有多棒。但是,我倾向于不使用super(),因为它使一切都比我想要的要复杂得多。我见过一些使用super()的流行示例,但它们似乎从未显示将位置所需的参数传递到基类构造函数中。

我知道Python中的菱形问题,而super()阻止了两次调用base_base类。(在本个案中属A类)

A类的构造函数会被调用两次吗?(即案件2)

下面是我对这两种情况的代码。

案例1:使用._ init _()

代码语言:javascript
复制
#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)

代码语言:javascript
复制
#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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-08 21:07:37

A类的构造函数会被调用两次吗?

当然,如果构造函数是缓慢的,或者是非幂等的,或者如果它获得资源,如文件句柄或数据库连接。在更复杂的继承结构中,您还可能会得到调用4次或6次的构造函数,或者从子继承图到祖先的继承图上的路径数。

我倾向于不使用超级(),因为它使一切比我想要的要复杂得多

这不是让事情变得复杂的super --而是多重继承。在多重继承中避免super只会给您带来不同的、可能比super的问题更糟糕的问题。

我见过一些使用super()的流行示例,但它们似乎从未显示将位置所需的参数传递到基类构造函数中。

这是因为位置构造函数参数在多重继承中不能很好地工作。如果您想要使用这样的多继承结构,请尝试只使用参数关键字,并使用**kwargs传递其他类要处理的不可识别的参数。“Python的超级()被认为是超级”对如何使其工作有一些很好的建议。

票数 1
EN

Stack Overflow用户

发布于 2016-03-08 21:15:53

super()的思想是支持方法分解顺序,这样您就可以使用合作继承编写程序。

如果您想调用超类的方法,合作继承是有意义的,但是您不知道具体的超类是什么--您只有一个假设,即该方法具有与您正在编写的方法相同的签名。

在您的示例中,每个__init__都是不同的,因此对于协作继承来说,这不是一个好的用例。每个类实际上都需要知道super的目标是什么,以便正确地调用它。因此,在这里您并没有从super中得到太多的好处。

让我们不要忘记:多重继承会导致混乱。为了让您的代码可以理解,并控制意大利面,您可以遵守一些约定(一系列限制)。一种方法是使用一些基类作为混合器。另一个想法是合作继承。Python有像super这样的语言构造来支持这些,但是如果您可以自由地走出这些边界。这与它自己的一系列问题有关。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35877911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档