我一直在研究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
这产生TyepError
第super
一种方法。super
会调用它首先识别并给出的任何方法实现,TypeError
而不是检查后续的其他类。但是,当我们执行以下操作时,这将更加清楚并且可以正常工作:
class Child(Base1, Base2):
def __init__(self):
Base1.__init__(self, 'Intended for base 1')
Base2.__init__(self) # Intended for base 2
这导致两个问题:
__init__
方法的静态方法或类方法?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] 删除。
我来说两句