2009-11-11 12 views
112

Ich bekomme einen Fehler, den ich nicht herausfinden kann. Irgendwelche Hinweise, was mit meinem Beispielcode nicht stimmt?Super() schlägt mit Fehler fehl: TypeError "Argument 1 muss Typ sein, nicht 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) 

Ich habe die Probe Test-Code von Hilfe von "Super" eingebauten Methode. Die Klasse "C" die hier

ist der Fehler:

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, hier ist die Hilfe (Super-) von Python selbst:

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

möglich duplikat von [python super() löst TypeError! Warum?] (Http://stackoverflow.com/questions/489269/python-super-raises-typeerror-why) – user

+1

Meth? Ist das ein Programmierbegriff oder ... weißt du? Bitte klären Sie. – Cplusplusplus

+2

@Cplusplusplus: wahrscheinlich steht für Methode ;-) – ShadowFlame

Antwort

197

Ihr Problem ist, dass die Klasse B ist nicht als "New-Style" -Klasse deklariert. Ändern Sie es so:

class B(object): 

und es wird funktionieren.

super() und alle Klassen der Unterklasse/Superklasse funktionieren nur mit neuen Klassen. Ich empfehle, dass Sie sich angewöhnen, immer das (object) für jede Klassendefinition einzugeben, um sicherzustellen, dass es sich um eine Klasse neuen Stils handelt.

Old-Style-Klassen (auch als "klassische" Klassen bezeichnet) sind immer vom Typ classobj; New-Style-Klassen sind vom Typ type. Aus diesem Grund ist die Fehlermeldung bekam man sah:

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

dieses Versuchen Sie selbst zu sehen:

class OldStyle: 
    pass 

class NewStyle(object): 
    pass 

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

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

Beachten Sie, dass in Python 3.x sind alle Klassen sind im neuen Stil. Sie können immer noch die Syntax der alten Klassen verwenden, aber Sie erhalten eine neue Stilklasse. In Python 3.x haben Sie dieses Problem nicht.

+0

interessant, ich fand genau dieses Problem laufen bottle.py (http://bottlepy.org), die einen ähnlichen Fehler (TypeError: muss Typ, nicht Classobj) auf Py27 ausgeführt werden aber nicht Py33. – bootload

+0

In Python 3.x gibt es keine "alten" Klassen mehr. Code, der die "old-style" -Deklaration verwendet, deklariert immer noch eine "new-style" -Klasse, daher kann dieser Fehler in Python 3.x nicht auftreten. – steveha

+0

Was passiert, wenn Klasse B nicht zur Bearbeitung verfügbar ist? –

92

Wenn Sie Klasse B nicht ändern können, können Sie den Fehler außerdem beheben, indem Sie Mehrfachvererbung verwenden.

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

'Objekt' als zweite Elternklasse ist ein netter Trick. –

+7

Ich konnte nicht helfen, einen Kommentar zu hinterlassen, dieser sollte als "Standard" -Antwort akzeptiert werden. – hylepo

+4

Für zukünftige Googler auf Python 2.6: das ist die Antwort, die Sie wahrscheinlich wollen! Wenn Sie die Basisklasse nicht ändern können (z. B. wenn Sie eine Standardbibliotheksklasse ableiten), wird durch diese Änderung an Ihrer eigenen Klasse super() korrigiert. – CoreDumpError

10

Wenn die Python-Version 3.X ist, ist es in Ordnung.

denke ich, Ihre Python-Version 2.x ist, funktionieren würde, die Super, wenn Sie diesen Code hinzufügen

__metaclass__ = type 

so der Code

__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

ich auch von dem entsandten Problem konfrontiert wurde, als ich verwendet Python 2.7. Es funktioniert sehr gut mit Python 3.4

Um es in Python 2.7 arbeiten zu lassen, habe ich das __metaclass__ = type Attribut an der Spitze meines Programms hinzugefügt und es hat funktioniert.

__metaclass__: Es erleichtert den Übergang von Old-Style-Klassen und New-Style-Klassen.

Verwandte Themen