您的代码与方法解析顺序无关。方法解决来自多重继承,这不是你的例子。您的代码是完全错误的,因为你认为self.__class__
实际上是同一类的一个地方被定义的方法,这是错误的:
>>> class A(object):
... def __init__(self):
... print self.__class__
...
>>>
>>> class B(A):
... def __init__(self):
... A.__init__(self)
...
>>> B()
<class '__main__.B'>
<__main__.B object at 0x1bcfed0>
>>> A()
<class '__main__.A'>
<__main__.A object at 0x1bcff90>
>>>
所以当你要拨打:
super(B, self).__init__(1, b, c)
你的确呼吁:
# super(self.__class__, self).__init__(1, b, c)
super(C, self).__init__(1, b, c)
编辑:试图更好地回答这个问题。
class A(object):
def __init__(self, a):
for cls in self.__class__.mro():
if cls is not object:
cls._init(self, a)
def _init(self, a):
print 'A._init'
self.a = a
class B(A):
def _init(self, a):
print 'B._init'
class C(A):
def _init(self, a):
print 'C._init'
class D(B, C):
def _init(self, a):
print 'D._init'
d = D(3)
print d.a
打印:
D._init
B._init
C._init
A._init
3
(的template pattern修改版本)。
现在,父母的方法实际上被隐含地称为,但我必须同意python禅,其中显式优于隐式,因为代码是较少可读性和增益较差。但要注意,所有_init
方法都有相同的参数,您不能完全忘记父母,我不建议这样做。
对于单继承,更好的方法是显式调用父类的方法,而不调用super
。这样做你不必命名当前类,但你仍然必须关心谁是父母的类。
好读是:how-does-pythons-super-do-the-right-thing在这个问题建议的链接和特殊性Python's Super is nifty, but you can't use it
如果层次结构可能会发生改变是糟糕的设计的症状,并在所有的部件后果谁正在使用的代码和不应该受到鼓励。
EDIT 2
另一个例子是我的想法,但它使用元类。 Urwid库uses metaclass在类中存储属性__super
,以便您只需访问该属性即可。
例:
>>> class MetaSuper(type):
... """adding .__super"""
... def __init__(cls, name, bases, d):
... super(MetaSuper, cls).__init__(name, bases, d)
... if hasattr(cls, "_%s__super" % name):
... raise AttributeError, "Class has same name as one of its super classes"
... setattr(cls, "_%s__super" % name, super(cls))
...
>>> class A:
... __metaclass__ = MetaSuper
... def __init__(self, a):
... self.a = a
... print 'A.__init__'
...
>>> class B(A):
... def __init__(self, a):
... print 'B.__init__'
... self.__super.__init__(a)
...
>>> b = B(42)
B.__init__
A.__init__
>>> b.a
42
>>>
我开始怀疑初始签名和多重继承 – 2010-05-04 03:14:34