超级可以处理多重继承吗? [英] Can Super deal with multiple inheritance?

查看:56
本文介绍了超级可以处理多重继承吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从这样的两个对象继承时

When inheriting from two objects like these

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

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

我通常会做这样的事情

class FooBar(Foo,Bar):
  def __init__(self,a,b):
    Foo.__init__(self,a)
    Bar.__init__(self,b)

超级怎么知道我是否要同时打电话给这两个人?如果是这样,它将如何知道将哪个参数传递到哪里.还是根本不可能在这里使用超级用户?

How does super know if I want to call both? and if so how will it know which argument to pass where. Or is it simply not possible to user super here?

即使Foo和Bar采取相同的论点,super能否处理呢?

Even if Foo and Bar take the same arguments can super deal with this?

还是我不应该一开始尝试这种方法?

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

推荐答案

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

Using super(), __init__() and multiple inheritance is a bit tricky.

在正常情况下,每个方法都会调用super(),仅继承自object的类会做一些额外的工作来确保该方法确实存在:会看起来像这样:

In the normal flow of things, every method calls super(), with the classes that inherit only from object doing a little extra work to make sure that the method actually exists: it'll look a bit like this:

>>> 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__不带参数,因此使用它的唯一安全方法是不带参数调用super().__init__(),因为该调用可能object.__init__处理.但是,它可能object.__init__处理,而是由继承图中其他地方的类处理.因此,必须准备在多继承类层次结构中定义__init__的任何任何类,而要使用无自变量进行调用.

But when you try to do something similar on a method that object actually has, things get a little dicey; object.__init__ doesn't take arguments, so about the only safe way to use it is to call super().__init__() with no arguments, since that call might be handled by object.__init__. But then it might not be handled by object.__init__, and instead handled by a class elsewhere in the inheritance graph. Thus any class which defines __init__ in a multiple inheritance class heirarchy must be prepared to be called with no arguments.

处理此问题的一种方法是永远不要使用__init__()中的参数.进行最少的初始化,并在使用前依靠设置属性或使用其他方式配置新对象.但是,那真是令人不快.

one way of dealing with this is to never use arguments in __init__(). Do minimal initialization, and rely on setting properties or using other means to configure the new object before use. That's pretty unpleasant, though.

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

Another way is to use only keyword arguments, something like def __init__(self, **keywords): and always remove the arguments that apply to the given constructor. This is a hope based strategy, you hope that all of the keywords get consumed before control reaches object.__init__.

第三种方法是为所有多个可继承的基类定义一个超类,该基类本身以某种有用的方式定义了__init__,并且没有 not 调用super().__init__(object.__init__是一个否-op).这意味着您可以确保始终将此方法称为last,并且可以根据需要随时进行操作.

A third way is to define a superclass to all of the multiple-inheritable bases which itself defines __init__ in some useful way and does not call super().__init__ (object.__init__ is a no-op anyway). This means you can be sure that this method is always called last, and you can do whetever you like with your arguments.

这篇关于超级可以处理多重继承吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆