2012-05-20 18 views

cevap

12

Python öğreticisinin yazarının hangi sınırlamalara başvurduğundan emin değilim, ancak, yöntemin/öznitelik aramasının python'da ("yöntem çözüm sırası") uygulanma biçimiyle ilgili olduğunu tahmin ediyorum. veya MRO). Python, C3 superclass linearization mekanizmasını kullanır; Bu, "The Diamond Problem" olarak adlandırılan şeyle uğraşmaktır.

Sınıf hiyerarşinize birden fazla devralma tanıttıktan sonra, herhangi bir sınıfın miras aldığı tek bir potansiyel sınıfı yoktur, yalnızca "MRO'da bir sonraki sınıfa" sahiptir. Özellikle bazı sınıflardan miras alırlar. Örneğin

, class A(object), class B(A), class C(A) ve class D(B, C), daha sonra sınıf D için MRO D->B->C->A ise. B Sınıfı yazılmış olabilir, muhtemelen A'dan geldiğini düşünüyordu ve kendi başına super()'u aradığında, A üzerinde bir yöntem olacaktır. Fakat bu artık doğru değil; B, super()'u çağırdığında, varsa C yerine bir yöntem alır.

Yöntem imzalarını geçersiz kılınmış yöntemlerde değiştirirseniz, bu sorun olabilir. Sınıf A, süper dediğinde A sınıfından bir yöntemin imzasını beklemek yerine, bu imzası olmayan (ve B sınıfının bakış açısından istenen davranışı uygulayamayabilir veya uygulayamayabilir) C'den bir yöntem alır. Bu kod örneğinde

class A(object): 
    def __init__(self, foo): 
     print "A!" 

class B(A): 
    def __init__(self, foo, bar): 
     print "B!" 
     super(B, self).__init__(foo) 

class C(A): 
    def __init__(self, foo, baaz): 
     print "C!" 
     super(C, self).__init__(foo) 

class D(B, C): 
    def __init__(self, foo, bar): 
     print "D!" 
     super(D, self).__init__(foo, bar) 

print D.mro() 
D("foo", "bar") 

, sınıflar B ve C makul A genişletilmiş ve onların __init__ imzaları değiştirdi, ancak doğru beklenen üst sınıf imzayı arasın. Böyle D yaparken süper çağırdığında Ama B'nin etkili "üst sınıf" yerine A. C olur, işler patlatmak:

[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>] 
D! 
B! 
Traceback (most recent call last): 
    File "/tmp/multi_inherit.py", line 22, in <module> 
    D("foo", "bar") 
    File "/tmp/multi_inherit.py", line 19, in __init__ 
    super(D, self).__init__(foo, bar) 
    File "/tmp/multi_inherit.py", line 9, in __init__ 
    super(B, self).__init__(foo) 
TypeError: __init__() takes exactly 3 arguments (2 given) 

şey aynı bu tür diğer yöntemler için de olabilirdi (super() diyorlarsa ve "elmas" yalnızca sınıf hiyerarşisinin kökünde görünmek zorunda değildir.

+7

Tüm bunlar doğrudur, ancak birden çok kalıtımı olan herhangi bir dil bu sorunları ele almak zorundadır. Cevabınızın doğru olduğunu varsayarsak, hangi dil (MI ile) * sınırlı bir çoklu kalıtım formuna sahip olmaz? –

İlgili konular