__init__是一个类方法吗?

蒂鲁文卡丹

我一直在研究Python的超级方法和多重继承。我读到类似的内容,例如当我们使用super调用在所有基类中都有实现的基方法时,即使具有各种参数,也只会调用一个类的方法。例如,

class Base1(object):
    def __init__(self, a):
        print "In Base 1"

class Base2(object):
    def __init__(self):
        print "In Base 2"

class Child(Base1, Base2):
    def __init__(self):
        super(Child, self).__init__('Intended for base 1')
        super(Child, self).__init__()# Intended for base 2

这产生TyepErrorsuper一种方法。super会调用它首先识别并给出的任何方法实现,TypeError而不是检查后续的其他类。但是,当我们执行以下操作时,这将更加清楚并且可以正常工作:

class Child(Base1, Base2):
    def __init__(self):
        Base1.__init__(self, 'Intended for base 1')
        Base2.__init__(self) # Intended for base 2

这导致两个问题:

  1. __init__方法的静态方法或类方法?
  2. 为什么要使用super,它会自己隐式选择方法,而不是像后面的示例那样显式调用该方法?对我来说,它看起来比使用super更干净。那么,使用super第二种方法有什么好处(除了通过方法调用编写基类名称之外)
单负消除

super()面对多重继承,尤其是在存在的方法上,object 可能会有些棘手一般规则是,如果使用super,则层次结构中的每个类都应使用super处理此问题的一种好方法__init__是使每个方法采用**kwargs,并且始终在各处使用关键字参数。到调用object.__init__发生时,所有参数都应该已经弹出!

class Base1(object):
    def __init__(self, a, **kwargs):
        print "In Base 1", a
        super(Base1, self).__init__()

class Base2(object):
    def __init__(self, **kwargs):
        print "In Base 2"
        super(Base2, self).__init__()

class Child(Base1, Base2):
    def __init__(self, **kwargs):
        super(Child, self).__init__(a="Something for Base1")

有关更多信息,请参见链接的文章,以了解更多信息。

编辑:冒着回答两个问题的风险:“为什么要完全使用超级?”

我们有super()许多的我们有类和继承同样的原因,对于模块化和提取我们的代码的工具。在类的实例上进行操作时,您无需了解该类的实现方式的所有详细信息,只需了解其方法和属性,以及使用该公共接口的方式上课 特别是,您可以确信,对类的实现进行的更改不会以实例用户的身份给您带来麻烦。

从基类派生新类型时,使用相同的参数。您不需要或不必担心这些基类是如何实现的。这是不使用super可能会出错的一个具体示例。假设您有:

class Foo(object):
     def frob(self):
         print "frobbign as a foo"
class Bar(object):
     def frob(self):
         print "frobbign as a bar"

然后创建一个子类:

class FooBar(Foo, Bar):
    def frob(self):
        Foo.frob(self)
        Bar.frob(self)

一切都很好,但是随后您意识到当您踏上这步时,Foo确实是一种Bar,所以您进行更改

 class Foo(Bar):
     def frob(self):
         print "frobbign as a foo"
         Bar.frob(self)

很好,除了在派生类中FooBar.frob()调用Bar.frob() 两次

这正是要super()解决的确切问题,它可以防止您多次调用超类实现(按指示使用时...)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用抽象的 __init__ 方法创建一个类?

实例化一个类,但不要调用它的__init__方法

如何从另一个类的 __init__ 访问类的属性?

在 __init__ 内部或外部的类中实例化一个类有什么区别?

为什么从另一个文件导入类会调用__init__函数?

如何测试一个在其 __init__ 中创建到数据库的连接的类?

使用来自另一个类的 __init__ 值

将实例传递给__init__。这是一个好主意吗?

在基类__init__的子类__init__之后调用基类方法吗?

是否可以使用来自调用另一个类的类的 __init__ 值?

使用继承另一个元类的元类时,子类的 super().__init__() 失败

是否可以通过来自同一个类的函数从类的 __init__ 访问变量?

为什么类需要一个 __init__ 函数来将参数传递给类实例?

在python中可以编写一个将在子类的__init__之后自动调用的方法

如何使用具有__init__方法的子类创建一个空对象?

如何通过单击具有多个框架的 tkinter 程序中的按钮将变量从一个类的 __init__ 传递到另一个类?

在Python中定义一个数据类的正确方法是什么?该数据类既具有自动生成的__init__,又具有根据值的dict附加的init2

python类的__init__方法

每次在Python类中是否都必须将__init__作为第一个函数?

是否可以在__init__函数中有条件地从一组固定的父类集中选择一个类的父类?

为什么在python中不可能有一个object方法返回一个元组作为新对象__init__方法中的参数?

为什么在python中不可能有一个object方法返回一个元组作为新对象__init__方法中的参数?

类型错误:__init__() 在另一个类中启动类时获得了意外的关键字参数

Scala:是一个类实例吗?

静态需要一个类吗?

在类方法中访问__init__ vars

模拟父类__init__方法

不能 Mockito 使用本机 init 方法模拟一个类

在 init 方法中启动线程是一个坏主意吗?