2009-11-20 20 views
9

İşte bir python oturumu.Alt sınıfta çağrılmayan meta sınıfı

>>> class Z(type): 
    def __new__(cls, name, bases, attrs): 
     print cls 
     print name 
     return type(name, bases, attrs) 
...  
>>> class Y(object): 
    __metaclass__ = Z 
...  
<class '__main__.Z'> 
Y 
>>> class X(Y): 
...  pass 
... 
>>> class W(Y): 
...  __metaclass__ = Z 
...  
<class '__main__.Z'> 
W 
>>> 

Sınıf XI Z._new__ bunun için çağrılacak bekliyoruz ve olmuyor iki çizgi, (metaclass devralınan olarak?) Yazdırmak tanımladıktan sonra

cevap

12

sorundur cls bağımsız değişkeni (metaclass nesnesidir), type'u çağırdığınızda iletilmez, bu nedenle oluşturulan ve döndürülen sınıf nesnesi Y, Z metaclassı için herhangi bir başvuruya sahip değildir. Eğer

return super(Z, cls).__new__(cls, name, bases, attrs) 

ile __new__ son satırı değiştirin

o zaman çalışır.numaralı belgede cls'un kullanılmasına rağmen1 numaralı argümanın hala bir argüman olarak belirtilmesi gerekir, çünkü super burada ilişkisiz bir yöntem döndürür (daha fazla bilgi için bkz. here). kullanabilirsiniz süper birini kullanarak alternatif olarak

:

return type.__new__(cls, name, bases, attrs) 

önemli olan classmethod __new__ için cls (bizim metaclass nesnesi Z) vermeniz. type(name, bases, attrs)'un daha kısa olan formu, cls argümanı için type bağımsız değişkenini doldurur. Bu hata, bir örnek yöntemini yanlış self bağımsız değişkeniyle çağırmaya benzer.

Bu daha iyi bir stil olduğundan super kullanmayı tercih ediyorum.

+2

Ah, tamam işte. Ama 'süper' (Z, cls) 'new__' dönüşü olmamalıdır' type .__ class __. New 'whis 'type' üzerinden yeni bir sınıf oluşturmakla aynı olması gereken type .__ new__' ile eşdeğerdir? – agiliq

+2

Aslında aynı değil, şimdi cevabımda bunu ele alıyorum. Super, 'type .__ new__' yöntemini çağırır, ancak doğru 'cls' argümanını kullanabiliriz; – nikow

İlgili konular