2009-11-11 16 views
112

Dostaję błąd, którego nie mogę znaleźć. Jakąkolwiek wskazówkę co jest nie tak z moim przykładowym kodem?super() kończy się niepowodzeniem z błędem: TypeError "argument 1 musi być typem, a nie classobj"

class B: 
    def meth(self, arg): 
     print arg 

class C(B): 
    def meth(self, arg): 
     super(C, self).meth(arg) 

print C().meth(1) 

Dostałem próbny kod testowy z pomocą "super" wbudowanej metody. Klasa "C" jest

Tutaj jest błąd:

Traceback (most recent call last): 
    File "./test.py", line 10, in ? 
    print C().meth(1) 
    File "./test.py", line 8, in meth 
    super(C, self).meth(arg) 
TypeError: super() argument 1 must be type, not classobj 

FYI, tutaj jest pomoc (super) z pytona samego:

Help on class super in module __builtin__: 

class super(object) 
| super(type) -> unbound super object 
| super(type, obj) -> bound super object; requires isinstance(obj, type) 
| super(type, type2) -> bound super object; requires issubclass(type2, type) 
| Typical use to call a cooperative superclass method: 
| class C(B): 
|  def meth(self, arg): 
|   super(C, self).meth(arg) 
| 
+0

możliwy duplikat [python super() podnosi TypeError! Dlaczego?] (Http://stackoverflow.com/questions/489269/python-super-raises-typeerror-why) – user

+1

Meth ?? Czy to termin programowania, czy ... no wiesz? Proszę o wyjaśnienie. – Cplusplusplus

+2

@Cplusplusplus: prawdopodobnie oznacza Method ;-) – ShadowFlame

Odpowiedz

197

Twoim problemem jest to, że klasa B nie został zadeklarowany jako klasa "nowego stylu". Zmień to tak:

class B(object): 

i będzie działać.

super() i wszystkie klasy podklasy/superklasy działają tylko z klasami w nowym stylu. Zalecam, abyś zawsze wpisywał tę (object) dla dowolnej definicji klasy, aby upewnić się, że jest to klasa nowego stylu.

Klasy w starym stylu (znane również jako klasyki "classic") są zawsze typu classobj; klasy nowego stylu są typu type. To dlatego, że masz komunikat o błędzie tnącej:

TypeError: super() argument 1 must be type, not classobj

Spróbuj to zobaczyć na własne oczy:

class OldStyle: 
    pass 

class NewStyle(object): 
    pass 

print type(OldStyle) # prints: <type 'classobj'> 

print type(NewStyle) # prints <type 'type'> 

Należy zauważyć, że w Pythonie 3.x, wszystkie zajęcia są nowym stylu. Nadal możesz używać składni ze starych klas, ale otrzymujesz klasę nowego stylu. Tak więc w Pythonie 3.x nie będziesz miał tego problemu.

+0

ciekawe, znalazłem ten dokładny problem z uruchomieniem bottle.py (http://bottlepy.org), który rzuca podobny błąd (TypeError: must be type, not classobj) uruchomiony na Py27 ale nie Py33. – bootload

+0

W Pythonie 3.x nie ma już klas "starego stylu". Kod używający deklaracji "starego stylu" nadal deklaruje klasę "nowego stylu", więc ten błąd nie może wystąpić w Pythonie 3.x. – steveha

+0

Co się stanie, jeśli klasa B nie jest dostępna do edycji? –

92

Ponadto, jeśli nie można zmienić klasy B, można naprawić błąd, stosując wiele dziedziczenia.

class B: 
    def meth(self, arg): 
     print arg 

class C(B, object): 
    def meth(self, arg): 
     super(C, self).meth(arg) 

print C().meth(1) 
+2

"Obiekt" jako druga klasa rodzica to fajna sztuczka. –

+7

Nie mogłem pomóc, aby dodać komentarz, ten powinien być przyjęty jako "standardowa" odpowiedź. – hylepo

+4

Dla przyszłych googlersów utknął w Python 2.6: jest to odpowiedź, której prawdopodobnie potrzebujesz! Jeśli nie można zmienić klasy bazowej (np. Podklasy klasy standardowej biblioteki), ta zmiana na własną klasę naprawia super(). – CoreDumpError

10

Jeśli wersja pytona jest 3.X, jest w porządku.

myślę wersja Pythona 2.X, super będzie działać po dodaniu tego kodu

__metaclass__ = type 

więc kod jest

__metaclass__ = type 
class B: 
    def meth(self, arg): 
     print arg 
class C(B): 
    def meth(self, arg): 
     super(C, self).meth(arg) 
print C().meth(1) 
2

Byłem też w obliczu problemu przez oddelegowanego kiedy używany python 2.7. Działa bardzo dobrze z pytonem 3.4

Aby działał w Pythonie 2.7 Dodałem atrybut __metaclass__ = type u góry mojego programu i zadziałało.

__metaclass__: Ułatwia przejście z zajęć w starym stylu i zajęć w nowym stylu.

Powiązane problemy