2012-02-09 13 views
5

Ho un metaclasse:metaclasse errore: Tipo .__ init __() prende 1 o 3 argomenti

class MyMeta(type): 
    def __init__(cls, name, bases, dct): 
     # Do something 
     ... 

     return super(MyMeta, cls).__init__(cls, name, bases, dct) 

e una classe:

class MyClass(object): 
    __metaclass__ = MyMeta 

Quando uso questi ottengo il seguente errore:

E  TypeError: Error when calling the metaclass bases 
E   type.__init__() takes 1 or 3 arguments 

Qual è il problema, e perché type.__init__() prende un numero di argomenti esattamente variabile?

risposta

8

Il problema è che nell'aggiornamento da python 2.5 a python 2.6 type.__init__() è stato modificato in modo tale che non è più necessario passare in cls. Così semplicemente fare il super chiamata:

return super(MyMeta, cls).__init__(name, bases, dct) 

Un'altra soluzione è quello di evitare la chiamata super del tutto e fare questo (anche se è un po 'meno bello):

return type.__init__(cls, name, bases, dct) 

E tutto funzionerà bene (in python > = 2.6).

Per quanto riguarda il motivo per cui type.__init__() può richiedere un numero diverso di argomenti, consultare the documentation. E 'così che, oltre ad usarlo come un costruttore, è possibile chiamare type(myobject) e restituirà il tipo di myobject:

>>> number = 1 
>>> type(number) 
<type 'int'> 
>>> type('my string') 
<type 'str'> 

Vedi What is a metaclass in Python? per ulteriori informazioni su metaclassi e tipo.

+3

Nota che 'super (MyMeta, cls) .__ init __ (name, bases, dct)' è il modo * corretto * di farlo, anche in 2.5 (e fino a 2.2). L'unico caso in cui passare 'cls' come primo argomento con' __new__', non con '__init__' (e non è specifico per' type' o metaclass.) Ciò che è cambiato è che 'type .__ init __()' ha smesso di ingoiare le eccezioni, molto simile 'oggetto .__ init __()'. –

+2

@ julio.alegria http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ –

+0

@HarleyHolcombe So che è possibile rispondere alla tua domanda, ma ... 30 secondi? Significa che la risposta era pronta prima ancora di aver postato la domanda, che è piuttosto strano – juliomalegria

Problemi correlati