2009-10-29 12 views
5

Als ich einige Tool-generierte Klassen erweiterte, erkannte ich nicht, dass sie Klassen im alten Stil sind, bis ich versuchte, super() zu verwenden. Die super() nicht mit alten Stil-Klassen arbeiten, also habe ich diesen Fehler:Ist es in Ordnung, alte und neue Stilklassen zu erweitern?

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

Eg, versuchen Sie diesen Schnipsel:

>>> class A: 
...  def greet(self): 
...   print "A says hi" 
... 
>>> class B(A): 
...  def greet(self): 
...   print "B says hi" 
... 
>>> super(B, B()).greet() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: super() argument 1 must be type, not classobj 

Ich war nur neugierig, was passieren würde, wenn ich B verlängert auch aus dem Objekt, um es zu einer neuen Stilklasse zu machen, und es schien super() zu funktionieren.

>>> class B(A, object): 
...  def greet(self): 
...   print "B says hi" 
... 
>>> super(B, B()).greet() 
A says hi 

Ist dies eine geeignete Problemumgehung oder habe ich später einige unerwünschte Folgen?

+2

Warum können Sie 'Klasse A' nicht in' KlasseA (Objekt) 'ändern? Was hindert Sie daran, die Ursache zu beheben und alles neu zu gestalten? Warum denkst du, dass eine Umgehung besser ist als eine Lösung? –

+1

Der Grund ist, dass die Klasse A generiert wird (wie ich eingangs erwähnt habe, erweitere ich vom Tool generierte Klassen). Wenn ich diese Änderung mache, werden die Klassen beim nächsten Generieren überschrieben. – haridsv

Antwort

1

Wenn Sie den Generator nicht ändern, um neue Stil-Klassen zu generieren, können Sie nachbearbeiten die Datei ihnen neuen Stil zu machen:

import re 
pat = re.compile("^(.*class\s+\w+)(:.*)$") 
out_file = open("edited_file.py", "w") 
for line in open("generated_file.py"): 
    m = pat.match(line) 
    if m: 
     line = m.group(1) + "(object)" + m.group(2) + "\n" 
    out_file.write(line) 

out_file.close() 

Wenn Sie nicht wollen, dass aus irgendeinem Grund zu tun , dann sicher, gehen Sie voran und Unterklasse sowohl die ursprüngliche Klasse und object. Nach meinem besten Wissen sollte das gut funktionieren; Ihre neue Klasse wird eine neue Klasse sein. Das Buch Python in a Nutshell (von Alex Martelli, veröffentlicht von O'Reilly) besagt, dass, wenn Sie eine Klasse mit Basisklassen deklarieren und mindestens eine der Basisklassen neu ist, es immer eine neue Stilklasse sein wird . Es enthält keine besonderen Warnungen oder Gefahren im Zusammenhang mit dieser Aktion. Ich denke du bist gut zu gehen.

4

Neue Klassen wurden in Python empfohlen, seit sie in Python 2.2 eingeführt wurden. In Python 3.x sind nur neue Stilklassen verfügbar. Daher empfehle ich, dass Sie Ihre Klassen in einen neuen Stil umwandeln.

Ich kenne keine wirklichen Probleme, die Sie daraus haben könnten. In den meisten Fällen bringen neue Klassen einfach neue Funktionen wie super(), die tatsächlich funktionieren. Wenn Sie Code haben, der auf die Semantik von Klassen alten Stils in trickreichen Wegen angewiesen ist, würde dieser Code natürlich brechen. (Das einzige Beispiel, das mir in den Sinn kommt, ist der berühmte Borg pattern des berühmten Alex Martelli.)

Here ist ein Link zum Python-Referenzhandbuch für eine Diskussion neuer Stilklassen vs. alten ("klassischen") Klassen . Und here ist ein Link zum klassischen Essay, wo Guido van Rossum erklärt, warum neue Klassen eingeführt wurden.

Ich verwende nur neue Stil Klassen in meinem Code und ich ermutige Sie, das gleiche zu tun.

+0

Danke für die interessanten Links.Sehen Sie meine letzten Kommentare, warum A im alten Stil ist. – haridsv

+0

Ich entschuldige mich, dass ich nicht verstanden habe, was Sie gefragt haben; Ich muss letzte Nacht müde gewesen sein, als ich das schrieb. Ich habe eine zweite Antwort geschrieben, die besser ist. – steveha

0

Ich sehe kein Problem Mischen von klassischen und neuen Stil-Klassen, es sei denn, einige Methoden verlassen sich auf klassische semantische oder Ihre klassische Basis verwendet Metaklasse (Metaklasse der Nachkommen wird immer eine neue Art-Klasse sein).

Auf der anderen Seite sehe ich keinen Grund, klassische Klassen mehr zu verwenden, so dass die Änderung class A: zu class A(object): bevorzugt wird.

+0

Ich würde dir zustimmen, aber Klasse A wird generiert. Für den Kontext ist das Tool, über das ich spreche, das ZSI-Paket, das die Tools wsdl2py und wsdl2dispatch bereitstellt. Sie wurden seit 2007 nicht mehr gepflegt und sind daher nicht sicher, wann sie es für Python 3.0 aktualisieren werden. Im Moment benutze ich immer noch 2.6, also habe ich kein Problem mit diesen generierten Klassen. Ich habe nicht einmal ein alternatives neueres Paket für das Implementieren des SOAP-Servers gesehen. – haridsv

Verwandte Themen