2009-11-20 20 views
9

Ecco una sessione python.Metaclass non viene chiamato nelle sottoclassi

>>> 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 
>>> 

Dopo definisco classe XI si aspettano Z._new__ di essere chiamato per questo, e per stampare la linea due, che non sta accadendo, (come metaclasse sono ereditati?)

risposta

12

Il problema è che l'argomento cls (che è l'oggetto metaclass) non viene passato quando si chiama type, pertanto l'oggetto classe Y creato e restituito non ha alcun riferimento alla metaclass Z.

Se si sostituisce l'ultima riga __new__ con

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

allora funziona. Si noti che, anche se cls viene utilizzato in super, dobbiamo ancora fornire cls come argomento, poiché super restituisce qui un metodo non associato (vedere here per ulteriori informazioni).

Come alternativa all'utilizzo di Super One potrebbe usare:

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

La cosa importante è che diamo cls (il nostro oggetto metaclasse Z) al classmethod __new__. Il modulo più corto type(name, bases, attrs) compila lo stesso type per l'argomento cls, che è ovviamente errato. Questo errore è simile alla chiamata di un metodo di istanza con l'argomento self errato.

Preferisco utilizzare super, poiché questo è lo stile migliore.

+2

Ah, ok, questo lavoro. Ma shouldnt 'return super (Z, cls) .__ new__' è equivalente a' type .__ class __. New' whis è equivalente a 'type .__ new__' che dovrebbe essere uguale alla creazione di una nuova classe tramite' type'? – agiliq

+2

In realtà non è la stessa cosa, ora lo affronterò nella mia risposta. Super chiama il metodo 'type .__ new__', ma possiamo usare l'argomento' cls' corretto, che non è possibile se chiamiamo direttamente 'type'. – nikow

Problemi correlati