超级能处理多重继承吗?

2024-05-20 03:13:59 发布

您现在位置:Python中文网/ 问答频道 /正文

从这两个对象继承时

class Foo(object):
  def __init__(self,a):
    self.a=a

class Bar(object):
  def __init__(self,b):
    self.b=b

我通常会这样做

^{pr2}$

super怎么知道我想不想两个都打?如果是这样的话,它又如何知道在哪里传递哪个论点呢。或者在这里根本不可能使用super?在

即使Foo和Bar使用相同的参数,super也能处理这个问题吗?在

或者我不应该一开始就尝试这样做吗?在


Tags: 对象self参数objectfooinitdefbar
2条回答

Or should I not be trying to do this kind of this in the first place?

正确。您应该只调用__init__s的一个父行,而不是树。super将使用MRO对父类进行深度优先搜索,以寻找要调用的__init__。它不会也不应该调用所有可能的__init__s

使用super()__init__()和多重继承有点棘手。在

在正常的流程中,每个方法调用super(),只从object继承的类做一些额外的工作以确保该方法确实存在:它看起来有点像:

>>> class Foo(object):
...     def frob(self, arg):
...         print "Foo.frob"
...         if hasattr(super(Foo, self), 'frob'):
...             super(Foo, self).frob(arg)
... 
>>> class Bar(object):
...     def frob(self, arg):
...         print "Bar.frob"
...         if hasattr(super(Bar, self), 'frob'):
...             super(Bar, self).frob(arg)
... 
>>> class Baz(Foo, Bar):
...     def frob(self, arg):
...         print "Baz.frob"
...         super(Baz, self).frob(arg)
... 
>>> b = Baz()
>>> b.frob(1)
Baz.frob
Foo.frob
Bar.frob
>>> 

但是当你试图在object实际拥有的方法上做类似的事情时,事情会变得有点冒险;object.__init__不带参数,所以使用它的唯一安全方法是不带参数地调用{},因为这个调用可能由object.__init__处理。但是,它可能由object.__init__处理,而不是由继承图中其他地方的类来处理。因此,在多重继承类继承结构中定义__init__的任何类都必须准备好在不使用任何参数的情况下调用类。在

处理此问题的一种方法是从不在__init__()中使用参数。进行最少的初始化,并在使用前依靠设置属性或使用其他方法配置新对象。不过,这很不愉快。在

另一种方法是只使用关键字参数,例如def __init__(self, **keywords):,并始终删除应用于给定构造函数的参数。这是一个基于hope的策略,您希望在控件到达object.__init__之前,所有的关键字都被消耗掉了。在

第三种方法是为所有多个可继承基定义一个超类,它本身以某种有用的方式定义了__init__,并且不调用super().__init__object.__init__无论如何都是不可操作的)。这意味着您可以确定这个方法总是最后调用的,并且您可以随意使用参数。在

相关问题 更多 >