Inkompatibilitäten zwischen Python 2.1[.x] und 2.2[.x]
<h3>Inkompatibilitäten zwischen Python 2.2.2 und Python 2.2.3</h3>
<p>Die folgenden sichtbaren Unterschiede zwischen Python 2.2.2 und Python 2.2.3 sind beabsichtigt.
<ul>
- <p><li>Es ist nicht mehr möglich, object.__setattr__ zu verwenden, um die
- Einschränkungen beim Setzen von Attributen von Typobjekten zu umgehen.
<p><li>list.extend() funktioniert mit jedem iterierbaren Objekt.
- <p><li>In pdb können Breakpoints nicht mehr mit negativen
- Nummern aktiviert werden.
<p><li>Die Module Bastion.py und rexec.py sind deaktiviert.
<p><li>Es gibt einige zusätzliche Einschränkungen bei __class__ Zuweisungen.
- <p><li>__delitem__ für WeakKeyDictionary wurde verbessert und behoben,
- kann aber das sichtbare Verhalten ändern.
</ul>
Siehe die <a href="../NEWS.txt">NEWS-Datei</a> für weitere Details.
<h3>Inkompatibilitäten zwischen Python 2.1[.x] und Python 2.2[.x]</h3>
<p>Die folgenden sichtbaren Unterschiede zwischen Python 2.2 und früheren Versionen sind beabsichtigt.
<ul>
<p><li>Hier sind nicht alle verschiedenen veralteten Module und Funktionen aufgeführt, die Warnungen ausgeben können: Die Warnungen sollten die korrekte Ausführung Ihres Programms nicht beeinträchtigen und können über eine Kommandozeilenoption oder programmatisch deaktiviert werden; siehe die Dokumentation des warnings-Moduls.
<p><li>Ebenfalls nicht aufgeführt sind neue Konstrukte, die früher ein Fehler waren (z.B. "key in dict" ist jetzt ein gültiger Test, wo früher immer eine Ausnahme ausgelöst worden wäre).
<p><li>Die Funktion dir() verhält sich anders als in Python 2.1 und davor. Im Allgemeinen gibt dir() mehr Informationen zurück als früher in 2.1. Zum Beispiel meldet dir([]) auch die speziellen Methoden, die verschiedene Operatoren überladen ('__add__', '__getitem__', '__len__', etc.) sowie '__class__'. Für Klassen (klassisch und neuartig) gibt sie die Attribute der Klasse sowie der Basisklassen zurück.
<p><li>Die speziellen Attribute __members__ und __methods__ werden nicht mehr unterstützt (für die meisten eingebauten Typen). Verwenden Sie stattdessen die neue und verbesserte dir()-Funktion.
<p><li>type("").__name__ == "str" # war "string"
<p><li>type(0L).__name__ == "long" # war "long int"
<p><li>Überlaufende int-Operationen geben den entsprechenden long-Wert zurück, anstatt die OverflowError-Ausnahme auszulösen.
<p><li>Die Konvertierung von long in float löst nun OverflowError aus, wenn das long zu groß ist, um als C-double dargestellt zu werden. Früher wurde auf den meisten Plattformen ein "unendlich"-Wert zurückgegeben.
<p><li>Die 3-Argument-builtin pow() erlaubt kein drittes Argument, das nicht None ist, wenn eines der ersten beiden Argumente ein float ist oder wenn beide vom Integer-Typ sind und das zweite Argument negativ ist (in letzterem Fall werden die Argumente in float konvertiert, also ist dies wirklich dieselbe Einschränkung).
<p><li>Ein alter Tokenizer-Bug erlaubte Gleitkommazahlen mit einem unvollständigen Exponenten, wie 1e und 3.1e-. Solche Literale lösen nun SyntaxError aus.
<p><li>Verschachtelte Geltungsbereiche sind in 2.2 Standard (sie wurden pro Modul durch "from __future__ import nested_scopes" in 2.1[.1] aktiviert). Dies kann die Bedeutung von Code wie dem folgenden ändern
- <pre>
- def f(<font color="red">str</font>)
- def g(x): return <font color="red">str</font>(x) return g
</pre>
In diesem Beispiel bezieht sich die Verwendung von <font color="red">str</font> innerhalb der inneren Funktion g() nun auf das Argument <font color="red">str</font> in der äußeren Funktion f(); früher (ohne verschachtelte Geltungsbereiche) hätte es sich auf die eingebaute Funktion <font color="blue">str</font> bezogen.
<p><li>Unbound method objects haben ihr im_class Feld anders gesetzt. In früheren Versionen wurde das im_class Feld auf die Klasse gesetzt, die die Methode <i>definiert</i> hat. Jetzt wird es auf die Klasse gesetzt, die zur Erstellung des Methodenobjekts verwendet wurde. Zum Beispiel
- <pre>
- class A
- def meth(self): ...
- class B(A)
- ... # definiert meth nicht
- class C(A)
- def meth(self)
- B.meth(self) # Fehler, C erbt nicht von B
</pre>
Dieser Code funktionierte vorher versehentlich, obwohl B keine Basisklasse von C ist, da B.meth.im_class auf A gesetzt war und A eine Basisklasse von C ist! Vermutlich war der Vererbungsbaum vor langer Zeit anders und C erbte von B; als dies geändert wurde, wurde der Aufruf nicht korrigiert. C wird fehlschlagen, wenn die nicht verwandte Klasse B eine neue Definition von meth() erhält. Außerdem gab früher B().meth.im_class A zurück; jetzt gibt es B zurück (da es sich um eine an eine Instanz von B gebundene Methode handelt).
<p><li>Die C API des GC-Moduls wurde inkompatibel geändert. Erweiterungen, die für die 2.1-Version des GC-Moduls geschrieben wurden, werden zwar noch kompiliert, aber die GC-Funktion wird deaktiviert.
<p><li>Der Inhalt von gc.garbage ist anders; er enthielt früher alle nicht sammelbaren Zyklen; jetzt enthält er nur Objekte in nicht sammelbaren Zyklen mit einer __del__ Methode.
<p><li>Die Hash-Reihenfolge von dict-Elementen ist anders als in früheren Versionen. (Kein Code sollte sich auf diese Reihenfolge verlassen, aber es ist leicht, dies zu vergessen.)
<p><li>Die Zuweisung an __debug__ löst zur Kompilierzeit SyntaxError aus.
<p><li>Der UTF-16-Codec wurde geändert, um RFC-konformer zu sein. Er wird nun nur noch BOM-Zeichen am Anfang des Strings entfernen und nur, wenn er im nativen Modus läuft (UTF-16-LE und -BE werden kein führendes BOM-Zeichen entfernen).
<p><li>Viele Fehlermeldungen sind anders; in einigen Fällen löst ein Fehlerzustand eine andere Ausnahme aus (am häufigsten sind Fälle, in denen TypeError und AttributeError vertauscht sind).
</ul>
<h3>Unterschiede zwischen klassischen und neuartigen Klassen</h3>
<p>Die folgenden Unterschiede zwischen klassischen und neuartigen Klassen können Aufmerksamkeit erfordern, wenn Sie eine klassische Klasse in eine neuartige Klasse konvertieren. Da frühere Versionen von Python neuartige Klassen nicht unterstützen, können diese nicht als echte Fehler betrachtet werden, aber da wir uns sehr bemüht haben, das Verhalten von neuartigen Klassen abwärtskompatibel zu gestalten, ist es wichtig, diese Unterschiede zu beachten. (Es gibt natürlich viele weitere Unterschiede, die relevant werden, wenn Sie eine neuartige Klasse von Grund auf neu schreiben; diese Liste enthält nur Verhaltensänderungen, die für die Konvertierung klassischer Klassen relevant sind.)
<ul>
<p><li>Die Method Resolution Order ist anders; siehe das <a href="../descrintro/#mro">Tutorial</a>.
<p><li>Neuartige Klassen, die binäre Operatoren überladen (__add__ und so weiter), können sich nicht auf die __coerce__ Methode verlassen, um die Argumente zu koarzieren; das andere Argument ist das, was ursprünglich vorhanden war. Wenn x also eine Instanz einer neuartigen Klasse ist, die eine __add__ Methode definiert, verursacht x+1 einen Aufruf von x.__add__(1). Die Methodenimplementierung muss den Typ des anderen Arguments analysieren, um die Operation korrekt implementieren zu können. Wenn die Methodenimplementierung entscheidet, dass sie die Operation für diese spezielle Kombination von Argumenttypen nicht implementieren kann, sollte sie den speziellen Singleton-Wert NotImplemented zurückgeben. (Dieses Verhalten ist dasselbe wie bei klassischen Klassen ohne __coerce__ Methode; der Unterschied besteht darin, dass die __coerce__ Methode von neuartigen binären Operatoren ignoriert wird.)
<p><li>Instanzen neuartiger Klassen erlauben Zuweisungen zum Attribut __class__ nur, wenn das C-Level-Strukturlayout der alten und neuen Klasse gleich ist. Dies verhindert Katastrophen wie das Nehmen einer Liste und das Ändern ihrer __class__, um sie zu einem Dictionary zu machen.
<p><li>Objekte neuartiger Klassen unterstützen keine Zuweisung an ihr __bases__ Attribut.
<p><li>Objekte neuartiger Klassen unterstützen keine Zuweisung an ihr __name__ Attribut.
<p><li>(Ich bin mir sicher, dass es noch mehr Unterschiede gibt, die für die Konvertierung von klassischen Klassen in neuartige Klassen relevant sind), aber mir fallen sie im Moment nicht ein.)
</ul>
<p>Um einen Fehler zu melden, der nicht oben aufgeführt ist, verwenden Sie immer den SourceForge <a href="http://sourceforge.net/bugs/?group_id=5470">Bug Tracker</a>. Wenn Sie einen Patch haben, verwenden Sie bitte den SourceForge <a href="http://sourceforge.net/patch/?group_id=5470">Patch Manager</a>. Bitte erwähnen Sie, dass Sie einen Fehler in 2.2.3 melden!
