您的代碼與方法解析順序無關。方法解決來自多重繼承,這不是你的例子。您的代碼是完全錯誤的,因爲你認爲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