2012-02-09 8 views
5

Mam metaklasa:metaklasa błąd: typ .__ startowych __() zajmuje 1 lub 3 argumenty

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

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

i klasę:

class MyClass(object): 
    __metaclass__ = MyMeta 

Kiedy używać tych pojawia się następujący błąd:

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

Na czym polega problem i dlaczego type.__init__() przyjmuje dokładnie zmienną liczbę argumentów?

Odpowiedz

8

Problem polega na tym, że podczas aktualizacji z Pythona 2.5 do Pythona 2.6 zmieniono type.__init__(), aby nie było już wymagane przekazywanie cls. Więc po prostu dokonać super połączenia:

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

Innym rozwiązaniem jest unikanie rozmowy super całkowicie i to zrobić (chociaż jest to trochę mniej ładne):

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

i wszystko będzie działać dobrze (w Pythonie > = 2,6).

Co do tego, dlaczego type.__init__() może przyjmować różne liczby argumentów, sprawdź numer the documentation. To tak, jak go używać jako konstruktor, można zadzwonić type(myobject) i powróci typ myobject:

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

Zobacz What is a metaclass in Python? Więcej informacji na temat metaclasses i typu.

+3

Zauważ, że 'super (MyMeta, cls) .__ init __ (name, bases, dct)' jest * poprawnym * sposobem na zrobienie tego, nawet w 2.5 (i aż do 2.2.) Jedyny przypadek, w którym Przekaż 'cls', ponieważ pierwszym argumentem jest' __new__', a nie '__init__' (i to nie jest specyficzne dla' type' lub metaclasses). Co zmieniło się, że 'type .__ init __()' przestał przełykać wyjątki, podobnie jak 'object .__ init __()'. –

+2

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

+0

@HarleyHolcombe Wiem, że odpowiedź na twoje pytanie jest dozwolona, ​​ale ... 30 sekund? Oznacza to, że odpowiedź była gotowa jeszcze przed opublikowaniem pytania, to trochę dziwne. – juliomalegria

Powiązane problemy