Was gibt es Neues in Python 2.3¶
- Autor:
A.M. Kuchling
Dieser Artikel erklärt die neuen Funktionen in Python 2.3. Python 2.3 wurde am 29. Juli 2003 veröffentlicht.
Die Hauptthemen für Python 2.3 sind die Verfeinerung einiger der in 2.2 hinzugefügten Funktionen, die Ergänzung verschiedener kleiner, aber nützlicher Verbesserungen an der Kernsprache und die Erweiterung der Standardbibliothek. Das in der vorherigen Version eingeführte neue Objektmodell hat von 18 Monaten Fehlerbehebungen und Optimierungsbemühungen profitiert, die die Leistung von Klassen im neuen Stil verbessert haben. Einige neue eingebaute Funktionen wie sum() und enumerate() wurden hinzugefügt. Der Operator in kann nun für die Suche nach Teilstrings verwendet werden (z. B. gibt "ab" in "abc" True zurück).
Einige der vielen neuen Bibliotheksfunktionen umfassen boolesche, Mengen-, Heap- und Datums-/Zeit-Datentypen, die Möglichkeit, Module aus ZIP-Archiven zu importieren, Metadatenunterstützung für den lange erwarteten Python-Katalog, eine aktualisierte Version von IDLE und Module für die Protokollierung von Nachrichten, Textumbruch, die Verarbeitung von CSV-Dateien, die Verarbeitung von Kommandozeilenoptionen, die Verwendung von BerkeleyDB-Datenbanken... die Liste der neuen und verbesserten Module ist lang.
Dieser Artikel versucht nicht, eine vollständige Spezifikation der neuen Funktionen zu geben, sondern bietet stattdessen einen praktischen Überblick. Für vollständige Details sollten Sie die Dokumentation für Python 2.3 konsultieren, wie z. B. das Python Library Reference und das Python Reference Manual. Wenn Sie die vollständige Implementierung und die Designbegründung verstehen möchten, konsultieren Sie die PEPs für eine bestimmte neue Funktion.
PEP 218: Ein standardmäßiger Set-Datentyp¶
Das neue Modul sets enthält eine Implementierung eines Set-Datentyps. Die Klasse Set ist für veränderliche Mengen, Mengen, denen Elemente hinzugefügt und entnommen werden können. Die Klasse ImmutableSet ist für Mengen, die nicht verändert werden können, und Instanzen von ImmutableSet können daher als Wörterbuchschlüssel verwendet werden. Mengen basieren auf Wörterbüchern, daher müssen die Elemente innerhalb einer Menge haschbar sein.
Hier ist ein einfaches Beispiel
>>> import sets
>>> S = sets.Set([1,2,3])
>>> S
Set([1, 2, 3])
>>> 1 in S
True
>>> 0 in S
False
>>> S.add(5)
>>> S.remove(3)
>>> S
Set([1, 2, 5])
>>>
Die Vereinigung und der Schnitt von Mengen können mit den Methoden union() und intersection() berechnet werden; eine alternative Notation verwendet die bitweisen Operatoren & und |. Veränderliche Mengen haben auch In-Place-Versionen dieser Methoden, union_update() und intersection_update().
>>> S1 = sets.Set([1,2,3])
>>> S2 = sets.Set([4,5,6])
>>> S1.union(S2)
Set([1, 2, 3, 4, 5, 6])
>>> S1 | S2 # Alternative notation
Set([1, 2, 3, 4, 5, 6])
>>> S1.intersection(S2)
Set([])
>>> S1 & S2 # Alternative notation
Set([])
>>> S1.union_update(S2)
>>> S1
Set([1, 2, 3, 4, 5, 6])
>>>
Es ist auch möglich, die symmetrische Differenz zweier Mengen zu bilden. Dies ist die Menge aller Elemente in der Vereinigung, die nicht im Schnitt enthalten sind. Anders ausgedrückt enthält die symmetrische Differenz alle Elemente, die in genau einer Menge enthalten sind. Auch hier gibt es eine alternative Notation (^) und eine In-Place-Version mit dem sperrigen Namen symmetric_difference_update().
>>> S1 = sets.Set([1,2,3,4])
>>> S2 = sets.Set([3,4,5,6])
>>> S1.symmetric_difference(S2)
Set([1, 2, 5, 6])
>>> S1 ^ S2
Set([1, 2, 5, 6])
>>>
Es gibt auch die Methoden issubset() und issuperset(), um zu prüfen, ob eine Menge eine Teilmenge oder Obermenge einer anderen ist.
>>> S1 = sets.Set([1,2,3])
>>> S2 = sets.Set([2,3])
>>> S2.issubset(S1)
True
>>> S1.issubset(S2)
False
>>> S1.issuperset(S2)
True
>>>
Siehe auch
- PEP 218 - Hinzufügen eines eingebauten Set-Objekttyps
PEP geschrieben von Greg V. Wilson. Implementiert von Greg V. Wilson, Alex Martelli und GvR.
PEP 255: Einfache Generatoren¶
In Python 2.2 wurden Generatoren als optionale Funktion hinzugefügt, die durch eine Anweisung from __future__ import generators aktiviert werden musste. In 2.3 müssen Generatoren nicht mehr speziell aktiviert werden und sind nun immer vorhanden; dies bedeutet, dass yield nun immer ein Schlüsselwort ist. Der Rest dieses Abschnitts ist eine Kopie der Beschreibung von Generatoren aus dem Dokument „What’s New in Python 2.2“; wenn Sie es beim Erscheinen von Python 2.2 gelesen haben, können Sie den Rest dieses Abschnitts überspringen.
Sie sind zweifellos damit vertraut, wie Funktionsaufrufe in Python oder C funktionieren. Wenn Sie eine Funktion aufrufen, erhält sie einen privaten Namensraum, in dem ihre lokalen Variablen erstellt werden. Wenn die Funktion eine return-Anweisung erreicht, werden die lokalen Variablen zerstört und der resultierende Wert an den Aufrufer zurückgegeben. Ein späterer Aufruf derselben Funktion erhält einen neuen Satz lokaler Variablen. Aber was wäre, wenn die lokalen Variablen beim Beenden einer Funktion nicht weggeworfen würden? Was wäre, wenn Sie die Funktion später dort fortsetzen könnten, wo Sie aufgehört haben? Dies bieten Generatoren, sie können als fortsetzbare Funktionen betrachtet werden.
Hier ist das einfachste Beispiel einer Generatorfunktion
def generate_ints(N):
for i in range(N):
yield i
Ein neues Schlüsselwort, yield, wurde für Generatoren eingeführt. Jede Funktion, die eine yield-Anweisung enthält, ist eine Generatorfunktion; dies wird vom Bytecode-Compiler von Python erkannt, der die Funktion dementsprechend speziell kompiliert.
Wenn Sie eine Generatorfunktion aufrufen, gibt sie keinen einzelnen Wert zurück, sondern ein Generatorobjekt, das das Iterator-Protokoll unterstützt. Bei Ausführung der yield-Anweisung gibt der Generator den Wert von i aus, ähnlich einer return-Anweisung. Der große Unterschied zwischen yield und einer return-Anweisung besteht darin, dass beim Erreichen eines yield der Ausführungszustand des Generators unterbrochen und die lokalen Variablen beibehalten werden. Beim nächsten Aufruf der Methode .next() des Generators wird die Funktion unmittelbar nach der yield-Anweisung fortgesetzt. (Aus komplizierten Gründen ist die yield-Anweisung im try-Block einer try...finally-Anweisung nicht erlaubt; lesen Sie PEP 255 für eine vollständige Erklärung der Interaktion zwischen yield und Ausnahmen.)
Hier ist ein Beispiel für die Verwendung des Generators generate_ints()
>>> gen = generate_ints(3)
>>> gen
<generator object at 0x8117f90>
>>> gen.next()
0
>>> gen.next()
1
>>> gen.next()
2
>>> gen.next()
Traceback (most recent call last):
File "stdin", line 1, in ?
File "stdin", line 2, in generate_ints
StopIteration
Sie könnten auch for i in generate_ints(5) schreiben oder a,b,c = generate_ints(3).
Innerhalb einer Generatorfunktion kann die return-Anweisung nur ohne Wert verwendet werden und signalisiert das Ende der Werteliste; danach kann der Generator keine weiteren Werte mehr zurückgeben. return mit einem Wert, wie z. B. return 5, ist eine Syntaxfehler innerhalb einer Generatorfunktion. Das Ende der Ergebnisse des Generators kann auch durch manuelles Auslösen von StopIteration oder durch einfaches Fallenlassen des Ausführungsflusses am Ende der Funktion angezeigt werden.
Man könnte den Effekt von Generatoren manuell erzielen, indem man seine eigene Klasse schreibt und alle lokalen Variablen des Generators als Instanzvariablen speichert. Zum Beispiel könnte die Rückgabe einer Liste von ganzen Zahlen erfolgen, indem self.count auf 0 gesetzt wird und die Methode next() self.count inkrementiert und zurückgibt. Für einen mäßig komplizierten Generator wäre das Schreiben einer entsprechenden Klasse jedoch viel unübersichtlicher. Lib/test/test_generators.py enthält eine Reihe interessanterer Beispiele. Das einfachste implementiert eine In-Order-Traversal eines Baumes mithilfe von Generatoren rekursiv.
# A recursive generator that generates Tree leaves in in-order.
def inorder(t):
if t:
for x in inorder(t.left):
yield x
yield t.label
for x in inorder(t.right):
yield x
Zwei weitere Beispiele in Lib/test/test_generators.py liefern Lösungen für das N-Damen-Problem (Platzieren von $N$ Damen auf einem $NxN$ Schachbrett, so dass keine Dame eine andere bedroht) und den Springerlauf (eine Route, die einen Springer zu jedem Feld eines $NxN$ Schachbretts führt, ohne ein Feld zweimal zu besuchen).
Die Idee der Generatoren stammt aus anderen Programmiersprachen, insbesondere aus Icon (https://www2.cs.arizona.edu/icon/), wo die Idee der Generatoren zentral ist. In Icon verhält sich jeder Ausdruck und Funktionsaufruf wie ein Generator. Ein Beispiel aus „An Overview of the Icon Programming Language“ unter https://www2.cs.arizona.edu/icon/docs/ipd266.htm gibt eine Vorstellung davon, wie das aussieht
sentence := "Store it in the neighboring harbor"
if (i := find("or", sentence)) > 5 then write(i)
In Icon gibt die Funktion find() die Indizes zurück, an denen die Teilzeichenkette „or“ gefunden wird: 3, 23, 33. In der if-Anweisung wird i zuerst der Wert 3 zugewiesen, aber 3 ist kleiner als 5, daher schlägt der Vergleich fehl, und Icon versucht ihn mit dem zweiten Wert 23 erneut. 23 ist größer als 5, daher gelingt der Vergleich nun, und der Code gibt den Wert 23 auf dem Bildschirm aus.
Python geht bei der Übernahme von Generatoren als zentrales Konzept bei weitem nicht so weit wie Icon. Generatoren gelten als Teil der Kernsprache Python, aber das Erlernen oder Verwenden ist nicht verpflichtend; wenn sie keine Probleme lösen, die Sie haben, können Sie sie gerne ignorieren. Ein neuartiges Merkmal von Pythons Schnittstelle im Vergleich zu der von Icon ist, dass der Zustand eines Generators durch ein konkretes Objekt (den Iterator) repräsentiert wird, das an andere Funktionen übergeben oder in einer Datenstruktur gespeichert werden kann.
Siehe auch
- PEP 255 - Einfache Generatoren
Geschrieben von Neil Schemenauer, Tim Peters, Magnus Lie Hetland. Implementiert hauptsächlich von Neil Schemenauer und Tim Peters, mit weiteren Korrekturen von der Python Labs Crew.
PEP 263: Source Code Encodings¶
Python-Quellcodedateien können nun so deklariert werden, dass sie in verschiedenen Zeichensatzkodierungen vorliegen. Kodierungen werden deklariert, indem ein speziell formatierter Kommentar in der ersten oder zweiten Zeile der Quelldatei enthalten ist. Eine UTF-8-Datei kann beispielsweise deklariert werden mit
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
Ohne eine solche Kodierungsdeklaration ist die verwendete Standardkodierung 7-Bit-ASCII. Die Ausführung oder der Import von Modulen, die Zeichenfolgenliterale mit 8-Bit-Zeichen enthalten und keine Kodierungsdeklaration haben, führt dazu, dass Python 2.3 eine DeprecationWarning auslöst; in 2.4 wird dies ein Syntaxfehler sein.
Die Kodierungsdeklaration beeinflusst nur Unicode-Zeichenfolgenliterale, die mit der angegebenen Kodierung in Unicode konvertiert werden. Beachten Sie, dass Python-Bezeichner immer noch auf ASCII-Zeichen beschränkt sind, sodass Sie keine Variablennamen haben können, die Zeichen außerhalb der üblichen alphanumerischen Zeichen verwenden.
Siehe auch
- PEP 263 - Definieren von Python-Quellcode-Kodierungen
Geschrieben von Marc-André Lemburg und Martin von Löwis; implementiert von Suzuki Hisao und Martin von Löwis.
PEP 273: Importieren von Modulen aus ZIP-Archiven¶
Das neue Modul zipimport fügt Unterstützung für den Import von Modulen aus ZIP-Archiven hinzu. Sie müssen das Modul nicht explizit importieren; es wird automatisch importiert, wenn der Dateiname eines ZIP-Archivs zu sys.path hinzugefügt wird. Zum Beispiel
amk@nyman:~/src/python$ unzip -l /tmp/example.zip
Archive: /tmp/example.zip
Length Date Time Name
-------- ---- ---- ----
8467 11-26-02 22:30 jwzthreading.py
-------- -------
8467 1 file
amk@nyman:~/src/python$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32)
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip') # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'
>>>
Ein Eintrag in sys.path kann nun der Dateiname eines ZIP-Archivs sein. Das ZIP-Archiv kann beliebige Dateitypen enthalten, aber nur Dateien mit den Namen *.py, *.pyc oder *.pyo können importiert werden. Wenn ein Archiv nur *.py-Dateien enthält, versucht Python nicht, das Archiv zu ändern, indem es die entsprechende *.pyc-Datei hinzufügt. Das bedeutet, dass der Import ziemlich langsam sein kann, wenn ein ZIP-Archiv keine *.pyc-Dateien enthält.
Ein Pfad innerhalb des Archivs kann auch angegeben werden, um nur aus einem Unterverzeichnis zu importieren; zum Beispiel würde der Pfad /tmp/example.zip/lib/ nur aus dem Unterverzeichnis lib/ im Archiv importieren.
Siehe auch
- PEP 273 - Importieren von Modulen aus Zip-Archiven
Geschrieben von James C. Ahlstrom, der auch eine Implementierung bereitgestellt hat. Python 2.3 folgt der Spezifikation in PEP 273, verwendet aber eine Implementierung von Just van Rossum, die die in PEP 302 beschriebenen Import-Hooks verwendet. Siehe Abschnitt PEP 302: Neue Import-Hooks für eine Beschreibung der neuen Import-Hooks.
PEP 277: Unicode-Dateinamenunterstützung für Windows NT¶
Unter Windows NT, 2000 und XP speichert das System Dateinamen als Unicode-Zeichenfolgen. Traditionell hat Python Dateinamen als Byte-Zeichenfolgen dargestellt, was unzureichend ist, da es einige Dateinamen unzugänglich macht.
Python erlaubt nun die Verwendung beliebiger Unicode-Zeichenfolgen (innerhalb der Einschränkungen des Dateisystems) für alle Funktionen, die Dateinamen erwarten, insbesondere die eingebaute Funktion open(). Wenn eine Unicode-Zeichenfolge an os.listdir() übergeben wird, gibt Python nun eine Liste von Unicode-Zeichenfolgen zurück. Eine neue Funktion, os.getcwdu(), gibt das aktuelle Verzeichnis als Unicode-Zeichenfolge zurück.
Byte-Zeichenfolgen funktionieren weiterhin als Dateinamen, und unter Windows konvertiert Python sie transparent in Unicode unter Verwendung der mbcs-Kodierung.
Andere Systeme erlauben ebenfalls Unicode-Zeichenfolgen als Dateinamen, konvertieren sie aber in Byte-Zeichenfolgen, bevor sie an das System übergeben werden, was zu einer UnicodeError führen kann. Anwendungen können testen, ob beliebige Unicode-Zeichenfolgen als Dateinamen unterstützt werden, indem sie os.path.supports_unicode_filenames, einen booleschen Wert, überprüfen.
Unter MacOS kann os.listdir() nun Unicode-Dateinamen zurückgeben.
Siehe auch
- PEP 277 - Unicode-Dateinamenunterstützung für Windows NT
Geschrieben von Neil Hodgson; implementiert von Neil Hodgson, Martin von Löwis und Mark Hammond.
PEP 278: Universal Newline Support¶
Die drei heute gebräuchlichsten Betriebssysteme sind Microsoft Windows, Apples Macintosh OS und die verschiedenen Unix-Derivate. Eine kleine Irritation bei plattformübergreifender Arbeit ist, dass diese drei Plattformen unterschiedliche Zeichen zur Kennzeichnung von Zeilenenden in Textdateien verwenden. Unix verwendet den Zeilenvorschub (ASCII-Zeichen 10), MacOS verwendet den Wagenrücklauf (ASCII-Zeichen 13) und Windows verwendet eine Zwei-Zeichen-Sequenz aus Wagenrücklauf plus Zeilenvorschub.
Python-Dateiobjekte können nun Ende-der-Zeile-Konventionen unterstützen, die von der Plattform abweichen, auf der Python läuft. Das Öffnen einer Datei im Modus 'U' oder 'rU' öffnet eine Datei zum Lesen im Modus Universal Newlines. Alle drei Konventionen für Zeilenenden werden in ein '\n' in den von den verschiedenen Datei-Methoden wie read() und readline() zurückgegebenen Zeichenfolgen übersetzt.
Der universelle Zeilenende-Support wird auch beim Importieren von Modulen und beim Ausführen einer Datei mit der Funktion execfile() verwendet. Das bedeutet, dass Python-Module zwischen allen drei Betriebssystemen gemeinsam genutzt werden können, ohne dass die Zeilenenden konvertiert werden müssen.
Diese Funktion kann beim Kompilieren von Python deaktiviert werden, indem der Schalter --without-universal-newlines beim Ausführen des configure-Skripts von Python angegeben wird.
Siehe auch
- PEP 278 - Universal Newline Support
Geschrieben und implementiert von Jack Jansen.
PEP 279: enumerate()¶
Eine neue eingebaute Funktion, enumerate(), wird bestimmte Schleifen etwas übersichtlicher machen. enumerate(thing), wobei thing entweder ein Iterator oder eine Sequenz ist, gibt einen Iterator zurück, der (0, thing[0]), (1, thing[1]), (2, thing[2]) und so weiter zurückgibt.
Ein gängiges Idiom zur Änderung jedes Elements einer Liste sieht so aus
for i in range(len(L)):
item = L[i]
# ... compute some result based on item ...
L[i] = result
Dies kann mit enumerate() umgeschrieben werden als
for i, item in enumerate(L):
# ... compute some result based on item ...
L[i] = result
Siehe auch
- PEP 279 - Die eingebaute Funktion enumerate()
Geschrieben und implementiert von Raymond D. Hettinger.
PEP 282: Das logging-Paket¶
Ein Standardpaket zum Schreiben von Protokollen, logging, wurde zu Python 2.3 hinzugefügt. Es bietet einen leistungsstarken und flexiblen Mechanismus zur Erzeugung von Protokollausgaben, die dann auf verschiedene Weise gefiltert und verarbeitet werden können. Eine Konfigurationsdatei in einem Standardformat kann verwendet werden, um das Protokollierungsverhalten eines Programms zu steuern. Python enthält Handler, die Protokollsätze an Standardfehler oder an eine Datei oder Socket schreiben, sie an das Systemprotokoll senden oder sie sogar per E-Mail an eine bestimmte Adresse senden; natürlich ist es auch möglich, eigene Handler-Klassen zu schreiben.
Die Klasse Logger ist die Hauptklasse. Die meisten Anwendungscodes werden mit einem oder mehreren Logger-Objekten arbeiten, die jeweils von einem bestimmten Subsystem der Anwendung verwendet werden. Jeder Logger wird durch einen Namen identifiziert, und Namen sind in einer Hierarchie organisiert, wobei . als Trennzeichen für Komponenten verwendet wird. Sie könnten beispielsweise Logger-Instanzen mit den Namen server, server.auth und server.network haben. Letztere beiden Instanzen stehen in der Hierarchie unter server. Das bedeutet, dass, wenn Sie die Ausführlichkeit für server erhöhen oder server-Nachrichten an einen anderen Handler leiten, die Änderungen auch für Datensätze gelten, die an server.auth und server.network gesendet werden. Es gibt auch einen Root-Logger, der das Elternteil aller anderen Logger ist.
Für einfache Anwendungen enthält das Paket logging einige Komfortfunktionen, die immer den Root-Log verwenden.
import logging
logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')
Dies erzeugt die folgende Ausgabe.
WARNING:root:Warning:config file server.conf not found
ERROR:root:Error occurred
CRITICAL:root:Critical error -- shutting down
In der Standardkonfiguration werden Informations- und Debugging-Nachrichten unterdrückt und die Ausgabe an Standardfehler gesendet. Sie können die Anzeige von Informations- und Debugging-Nachrichten aktivieren, indem Sie die Methode setLevel() auf dem Root-Logger aufrufen.
Beachten Sie die Verwendung von String-Formatierungsoperatoren im Aufruf von warning(); alle Funktionen zum Protokollieren von Nachrichten nehmen die Argumente (msg, arg1, arg2, ...) und protokollieren die Zeichenfolge, die sich aus msg % (arg1, arg2, ...) ergibt.
Es gibt auch eine Funktion exception(), die den letzten Traceback aufzeichnet. Jede der anderen Funktionen zeichnet ebenfalls den Traceback auf, wenn Sie einen wahren Wert für das Schlüsselwortargument exc_info angeben.
def f():
try: 1/0
except: logging.exception('Problem recorded')
f()
Dies erzeugt die folgende Ausgabe.
ERROR:root:Problem recorded
Traceback (most recent call last):
File "t.py", line 6, in f
1/0
ZeroDivisionError: integer division or modulo by zero
Etwas fortgeschrittenere Programme verwenden einen anderen Logger als den Root-Logger. Die Funktion getLogger(name) wird verwendet, um einen bestimmten Log abzurufen, und erstellt ihn, falls er noch nicht existiert. getLogger(None) gibt den Root-Logger zurück.
log = logging.getLogger('server')
...
log.info('Listening on port %i', port)
...
log.critical('Disk full')
...
Log-Datensätze werden normalerweise die Hierarchie hinauf propagiert, sodass eine an server.auth gesendete Nachricht auch von server und root gesehen wird, aber ein Logger kann dies verhindern, indem er sein Attribut propagate auf False setzt.
Es gibt weitere Klassen, die vom Paket logging bereitgestellt werden und angepasst werden können. Wenn eine Logger-Instanz angewiesen wird, eine Nachricht zu protokollieren, erstellt sie eine LogRecord-Instanz, die an beliebig viele verschiedene Handler-Instanzen gesendet wird. Logger und Handler können auch eine angehängte Liste von Filtern haben, und jeder Filter kann dazu führen, dass der LogRecord ignoriert wird oder den Datensatz modifizieren kann, bevor er weitergegeben wird. Wenn sie schließlich ausgegeben werden, werden LogRecord-Instanzen von einer Formatter-Klasse in Text konvertiert. All diese Klassen können durch Ihre eigenen, speziell geschriebenen Klassen ersetzt werden.
Mit all diesen Funktionen sollte das Paket logging selbst für die kompliziertesten Anwendungen ausreichend Flexibilität bieten. Dies ist nur ein unvollständiger Überblick über seine Funktionen. Bitte beachten Sie die Referenzdokumentation des Pakets für alle Details. Das Lesen von PEP 282 wird ebenfalls hilfreich sein.
Siehe auch
- PEP 282 - Ein Protokollsystem
Geschrieben von Vinay Sajip und Trent Mick; implementiert von Vinay Sajip.
PEP 285: Ein Boolescher Typ¶
Ein boolescher Typ wurde zu Python 2.3 hinzugefügt. Zwei neue Konstanten wurden dem Modul __builtin__ hinzugefügt: True und False. (Die Konstanten True und False wurden in Python 2.2.1 zu den Built-ins hinzugefügt, aber die Versionen von 2.2.1 sind einfach auf die Ganzzahlwerte 1 und 0 gesetzt und sind kein anderer Typ.)
Das Typobjekt für diesen neuen Typ heißt bool; der Konstruktor dafür nimmt jeden Python-Wert und wandelt ihn in True oder False um.
>>> bool(1)
True
>>> bool(0)
False
>>> bool([])
False
>>> bool( (1,) )
True
Die meisten Standardbibliotheksmodule und integrierten Funktionen wurden geändert, um Booleans zurückzugeben.
>>> obj = []
>>> hasattr(obj, 'append')
True
>>> isinstance(obj, list)
True
>>> isinstance(obj, tuple)
False
Pythons Booleans wurden mit dem Hauptziel hinzugefügt, Code klarer zu machen. Wenn Sie zum Beispiel eine Funktion lesen und auf die Anweisung return 1 stoßen, fragen Sie sich vielleicht, ob die 1 einen booleschen Wahrheitswert, einen Index oder einen Koeffizienten darstellt, der eine andere Menge multipliziert. Wenn die Anweisung jedoch return True lautet, ist die Bedeutung des Rückgabewerts ziemlich klar.
Pythons Booleans wurden *nicht* zur strengen Typüberprüfung hinzugefügt. Eine sehr strenge Sprache wie Pascal würde Ihnen auch verbieten, Arithmetik mit Booleans durchzuführen, und würde verlangen, dass der Ausdruck in einer if-Anweisung immer zu einem booleschen Ergebnis ausgewertet wird. Python ist nicht so streng und wird es auch nie sein, wie PEP 285 explizit besagt. Das bedeutet, dass Sie immer noch jeden Ausdruck in einer if-Anweisung verwenden können, auch solche, die zu einer Liste, einem Tupel oder einem zufälligen Objekt ausgewertet werden. Der boolesche Typ ist eine Unterklasse der int-Klasse, sodass Arithmetik mit einem Boolean immer noch funktioniert.
>>> True + 1
2
>>> False + 1
1
>>> False * 75
0
>>> True * 75
75
Um True und False in einem Satz zusammenzufassen: Sie sind alternative Schreibweisen für die Ganzzahlwerte 1 und 0, mit dem einzigen Unterschied, dass str() und repr() die Zeichenketten 'True' und 'False' anstelle von '1' und '0' zurückgeben.
Siehe auch
- PEP 285 - Hinzufügen eines bool-Typs
Geschrieben und implementiert von GvR.
PEP 293: Callbacks zur Behandlung von Codec-Fehlern¶
Beim Kodieren eines Unicode-Strings in einen Byte-String können nicht kodierbare Zeichen auftreten. Bisher erlaubte Python die Angabe der Fehlerbehandlung als „strict“ (Auslösung eines UnicodeError), „ignore“ (Überspringen des Zeichens) oder „replace“ (Verwendung eines Fragezeichens im Ausgabestring), wobei „strict“ das Standardverhalten war. Es kann wünschenswert sein, alternative Verarbeitungen solcher Fehler anzugeben, wie z. B. das Einfügen einer XML-Zeichenreferenz oder einer HTML-Entitätsreferenz in den konvertierten String.
Python verfügt nun über ein flexibles Framework zur Ergänzung verschiedener Verarbeitungsstrategien. Neue Fehlerbehandler können mit codecs.register_error() hinzugefügt werden, und Codecs können den Fehlerbehandler dann mit codecs.lookup_error() abrufen. Eine äquivalente C-API wurde für in C geschriebene Codecs hinzugefügt. Der Fehlerbehandler erhält die notwendigen Zustandsinformationen wie den zu konvertierenden String, die Position im String, an der der Fehler erkannt wurde, und die Zielkodierung. Der Behandler kann dann entweder eine Ausnahme auslösen oder einen Ersatzstring zurückgeben.
Zwei zusätzliche Fehlerbehandler wurden mit diesem Framework implementiert: „backslashreplace“ verwendet die Python-Backslash-Zitierung, um nicht kodierbare Zeichen darzustellen, und „xmlcharrefreplace“ gibt XML-Zeichenreferenzen aus.
Siehe auch
- PEP 293 - Codec-Fehlerbehandlungs-Callbacks
Geschrieben und implementiert von Walter Dörwald.
PEP 301: Paketindex und Metadaten für Distutils¶
Unterstützung für den seit langem gewünschten Python-Katalog hält in 2.3 erstmals Einzug.
Das Herzstück des Katalogs ist der neue Distutils-Befehl register. Das Ausführen von python setup.py register sammelt die Metadaten, die ein Paket beschreiben, wie z. B. Name, Version, Betreuer, Beschreibung usw., und sendet sie an einen zentralen Katalogserver. Der resultierende Katalog ist unter https://pypi.org verfügbar.
Um den Katalog etwas nützlicher zu machen, wurde der Distutils-Funktion setup() ein neues optionales Schlüsselwortargument *classifiers* hinzugefügt. Eine Liste von Strings im Trove-Stil kann angegeben werden, um die Software zu klassifizieren.
Hier ist ein Beispiel für eine setup.py mit Klassifikatoren, geschrieben, um mit älteren Versionen von Distutils kompatibel zu sein
from distutils import core
kw = {'name': "Quixote",
'version': "0.5.1",
'description': "A highly Pythonic Web application framework",
# ...
}
if (hasattr(core, 'setup_keywords') and
'classifiers' in core.setup_keywords):
kw['classifiers'] = \
['Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Environment :: No Input/Output (Daemon)',
'Intended Audience :: Developers'],
core.setup(**kw)
Die vollständige Liste der Klassifikatoren kann durch Ausführen von python setup.py register --list-classifiers abgerufen werden.
Siehe auch
- PEP 301 - Paketindex und Metadaten für Distutils
Geschrieben und implementiert von Richard Jones.
PEP 302: Neue Import-Hooks¶
Obwohl es seit der Einführung des Moduls ihooks in Python 1.3 möglich war, benutzerdefinierte Import-Hooks zu schreiben, war niemand wirklich zufrieden damit, da das Schreiben neuer Import-Hooks schwierig und unordentlich ist. Es gab verschiedene alternative Vorschläge wie die Module imputil und iu, aber keiner von ihnen hat je viel Akzeptanz gefunden, und keiner von ihnen war von C aus leicht verwendbar.
PEP 302 entlehnt Ideen aus seinen Vorgängern, insbesondere aus Gordon McMillans Modul iu. Drei neue Elemente werden dem Modul sys hinzugefügt
sys.path_hooksist eine Liste von aufrufbaren Objekten; meist werden es Klassen sein. Jeder Aufrufbare nimmt einen String entgegen, der einen Pfad enthält, und gibt entweder ein Importer-Objekt zurück, das Importe von diesem Pfad handhabt, oder löst eineImportError-Ausnahme aus, wenn es diesen Pfad nicht handhaben kann.sys.path_importer_cachespeichert Importer-Objekte für jeden Pfad zwischen, sodasssys.path_hooksnur einmal für jeden Pfad durchlaufen werden muss.sys.meta_pathist eine Liste von Importer-Objekten, die durchlaufen wird, bevorsys.pathüberprüft wird. Diese Liste ist anfangs leer, aber Benutzercode kann Objekte hinzufügen. Zusätzliche eingebaute und eingefrorene Module können von einem Objekt importiert werden, das dieser Liste hinzugefügt wurde.
Importer-Objekte müssen eine einzige Methode haben: find_module(fullname, path=None). *fullname* ist ein Modul- oder Paketname, z. B. string oder distutils.core. find_module() muss ein Loader-Objekt zurückgeben, das eine einzige Methode hat: load_module(fullname), das das entsprechende Modulobjekt erstellt und zurückgibt.
Pseudo-Code für Pythons neue Import-Logik sieht daher ungefähr so aus (etwas vereinfacht; siehe PEP 302 für die vollständigen Details)
for mp in sys.meta_path:
loader = mp(fullname)
if loader is not None:
<module> = loader.load_module(fullname)
for path in sys.path:
for hook in sys.path_hooks:
try:
importer = hook(path)
except ImportError:
# ImportError, so try the other path hooks
pass
else:
loader = importer.find_module(fullname)
<module> = loader.load_module(fullname)
# Not found!
raise ImportError
Siehe auch
- PEP 302 - Neue Import-Hooks
Geschrieben von Just van Rossum und Paul Moore. Implementiert von Just van Rossum.
PEP 305: Komma-getrennte Dateien¶
Komma-getrennte Dateien sind ein Format, das häufig zum Exportieren von Daten aus Datenbanken und Tabellenkalkulationen verwendet wird. Python 2.3 fügt einen Parser für komma-getrennte Dateien hinzu.
Das komma-getrennte Format ist auf den ersten Blick trügerisch einfach
Costs,150,200,3.95
Eine Zeile lesen und line.split(',') aufrufen: Was könnte einfacher sein? Aber wenn man Zeichenketten mit Kommas einbezieht, wird es komplizierter
"Costs",150,200,3.95,"Includes taxes, shipping, and sundry items"
Ein großes, hässliches reguläres Ausdrucksmuster kann dies parsen, aber die Verwendung des neuen Pakets csv ist viel einfacher
import csv
input = open('datafile', 'rb')
reader = csv.reader(input)
for line in reader:
print line
Die Funktion reader() nimmt eine Reihe verschiedener Optionen entgegen. Der Feldtrenner ist nicht auf das Komma beschränkt und kann durch jedes Zeichen geändert werden, ebenso wie die Zitat- und Zeilenendezeichen.
Verschiedene Dialekte von komma-getrennten Dateien können definiert und registriert werden; derzeit gibt es zwei Dialekte, beide von Microsoft Excel verwendet. Eine separate Klasse csv.writer generiert komma-getrennte Dateien aus einer Abfolge von Tupeln oder Listen und zitiert Zeichenketten, die den Trenner enthalten.
Siehe auch
- PEP 305 - CSV-Datei-API
Geschrieben und implementiert von Kevin Altis, Dave Cole, Andrew McNamara, Skip Montanaro, Cliff Wells.
PEP 307: Pickle-Erweiterungen¶
Die Module pickle und cPickle wurden während des Entwicklungszyklus von 2.3 einiger Aufmerksamkeit gewidmet. In 2.2 konnten neue Klassen ohne Schwierigkeiten gepickelt werden, aber sie wurden nicht sehr kompakt gepickelt; PEP 307 zitiert ein triviales Beispiel, bei dem eine neue Klasse zu einem gepickelten String führt, der dreimal länger ist als der für eine klassische Klasse.
Die Lösung bestand darin, ein neues Pickle-Protokoll zu erfinden. Die Funktion pickle.dumps() unterstützt seit langem ein Text- oder Binärflag. In 2.3 wird dieses Flag von einem Boolean zu einer Ganzzahl umdefiniert: 0 ist das alte Text-Mode-Pickle-Format, 1 ist das alte Binärformat und jetzt 2 ist ein neues 2.3-spezifisches Format. Eine neue Konstante, pickle.HIGHEST_PROTOCOL, kann verwendet werden, um das schickste verfügbare Protokoll auszuwählen.
Entpickeln wird nicht mehr als sichere Operation betrachtet. Das pickle von 2.2 bot Hooks, um zu versuchen, unsichere Klassen vom Entpickeln abzuhalten (insbesondere ein Attribut __safe_for_unpickling__), aber keiner dieser Codes wurde jemals geprüft und daher wurde alles in 2.3 entfernt. Sie sollten keine nicht vertrauenswürdigen Daten in irgendeiner Version von Python entpickeln.
Um den Pickle-Overhead für neue Klassen zu reduzieren, wurde eine neue Schnittstelle zur Anpassung des Pickling mit drei speziellen Methoden hinzugefügt: __getstate__(), __setstate__() und __getnewargs__(). Konsultieren Sie PEP 307 für die vollständige Semantik dieser Methoden.
Um Pickles noch weiter zu komprimieren, ist es nun möglich, Ganzzahlcodes anstelle von langen Zeichenketten zur Identifizierung von gepickelten Klassen zu verwenden. Die Python Software Foundation wird eine Liste standardisierter Codes pflegen; es gibt auch einen Bereich von Codes für den privaten Gebrauch. Derzeit wurden keine Codes spezifiziert.
Siehe auch
- PEP 307 - Erweiterungen des Pickle-Protokolls
Geschrieben und implementiert von Guido van Rossum und Tim Peters.
Erweiterte Slices¶
Seit Python 1.4 unterstützt die Slicing-Syntax ein optionales drittes „step“- oder „stride“-Argument. Zum Beispiel sind dies alles legale Python-Syntax: L[1:10:2], L[:-1:1], L[::-1]. Dies wurde auf Anfrage der Entwickler von Numerical Python zu Python hinzugefügt, das das dritte Argument ausgiebig verwendet. Die integrierten Listen-, Tupel- und String-Sequenztypen haben diese Funktion jedoch nie unterstützt und lösten eine TypeError aus, wenn Sie es versuchten. Michael Hudson trug einen Patch bei, um diese Einschränkung zu beheben.
Sie können beispielsweise jetzt leicht die Elemente einer Liste extrahieren, die gerade Indizes haben
>>> L = range(10)
>>> L[::2]
[0, 2, 4, 6, 8]
Negative Werte funktionieren ebenfalls, um eine Kopie derselben Liste in umgekehrter Reihenfolge zu erstellen
>>> L[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Dies funktioniert auch für Tupel, Arrays und Strings
>>> s='abcd'
>>> s[::2]
'ac'
>>> s[::-1]
'dcba'
Wenn Sie eine veränderliche Sequenz wie eine Liste oder ein Array haben, können Sie einer erweiterten Slice Werte zuweisen oder sie löschen, aber es gibt einige Unterschiede zwischen der Zuweisung zu erweiterten und regulären Slices. Die Zuweisung zu einer regulären Slice kann verwendet werden, um die Länge der Sequenz zu ändern
>>> a = range(3)
>>> a
[0, 1, 2]
>>> a[1:3] = [4, 5, 6]
>>> a
[0, 4, 5, 6]
Erweiterte Slices sind nicht so flexibel. Bei der Zuweisung zu einer erweiterten Slice muss die Liste auf der rechten Seite der Anweisung die gleiche Anzahl von Elementen enthalten wie die zu ersetzende Slice
>>> a = range(4)
>>> a
[0, 1, 2, 3]
>>> a[::2]
[0, 2]
>>> a[::2] = [0, -1]
>>> a
[0, 1, -1, 3]
>>> a[::2] = [0,1,2]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: attempt to assign sequence of size 3 to extended slice of size 2
Löschen ist unkomplizierter
>>> a = range(4)
>>> a
[0, 1, 2, 3]
>>> a[::2]
[0, 2]
>>> del a[::2]
>>> a
[1, 3]
Man kann nun auch Slice-Objekte an die Methoden __getitem__() der integrierten Sequenzen übergeben
>>> range(10).__getitem__(slice(0, 5, 2))
[0, 2, 4]
Oder Slice-Objekte direkt in Indizes verwenden
>>> range(10)[slice(0, 5, 2)]
[0, 2, 4]
Um die Implementierung von Sequenzen, die erweiterte Slicing unterstützen, zu vereinfachen, haben Slice-Objekte nun eine Methode indices(length), die bei gegebener Sequenzlänge ein Tupel (start, stop, step) zurückgibt, das direkt an range() übergeben werden kann. indices() behandelt ausgelassene und außerhalb des Bereichs liegende Indizes auf eine Weise, die mit regulären Slices konsistent ist (und dieser harmlose Satz verbirgt eine Fülle verwirrender Details!). Die Methode ist dafür gedacht, so verwendet zu werden
class FakeSeq:
...
def calc_item(self, i):
...
def __getitem__(self, item):
if isinstance(item, slice):
indices = item.indices(len(self))
return FakeSeq([self.calc_item(i) for i in range(*indices)])
else:
return self.calc_item(i)
Aus diesem Beispiel geht auch hervor, dass das integrierte Objekt slice nun der Typobjekt für den Slice-Typ ist und keine Funktion mehr ist. Dies steht im Einklang mit Python 2.2, wo int, str usw. die gleiche Änderung erfahren haben.
Andere Sprachänderungen¶
Hier sind alle Änderungen, die Python 2.3 an der Kernsprache Python vornimmt.
Die Anweisung
yieldist jetzt immer ein Schlüsselwort, wie in Abschnitt PEP 255: Simple Generators dieses Dokuments beschrieben.Eine neue integrierte Funktion
enumerate()wurde hinzugefügt, wie in Abschnitt PEP 279: enumerate() dieses Dokuments beschrieben.Zwei neue Konstanten,
TrueundFalse, wurden zusammen mit dem integrierten Typboolhinzugefügt, wie in Abschnitt PEP 285: A Boolean Type dieses Dokuments beschrieben.Der Typkonstruktor
int()gibt nun eine lange Ganzzahl zurück, anstatt eineOverflowErrorauszulösen, wenn ein String oder eine Fließkommazahl zu groß ist, um in eine Ganzzahl zu passen. Dies kann zu dem paradoxen Ergebnis führen, dassisinstance(int(expression), int)falsch ist, aber das scheint in der Praxis unwahrscheinlich Probleme zu verursachen.Integrierte Typen unterstützen nun die erweiterte Slicing-Syntax, wie in Abschnitt Erweiterte Slices dieses Dokuments beschrieben.
Eine neue integrierte Funktion,
sum(iterable, start=0), summiert die numerischen Elemente im iterierbaren Objekt und gibt ihre Summe zurück.sum()akzeptiert nur Zahlen, was bedeutet, dass Sie sie nicht verwenden können, um eine Reihe von Strings zu verketten. (Beigesteuert von Alex Martelli.)list.insert(pos, value)fügte früher value am Anfang der Liste ein, wenn pos negativ war. Das Verhalten wurde nun geändert, um mit der Slice-Indizierung konsistent zu sein. Wenn pos -1 ist, wird der Wert vor dem letzten Element eingefügt und so weiter.list.index(value), das nach value in der Liste sucht und dessen Index zurückgibt, nimmt nun optionale Argumente start und stop* an, um die Suche auf nur einen Teil der Liste zu beschränken.Dictionaries haben eine neue Methode,
pop(key[, *default*]), die den Wert zurückgibt, der key* entspricht, und dieses Schlüssel/Wert-Paar aus dem Dictionary entfernt. Wenn der angeforderte Schlüssel nicht im Dictionary vorhanden ist, wird default zurückgegeben, wenn es angegeben ist, und andernfalls wird eineKeyErrorausgelöst.>>> d = {1:2} >>> d {1: 2} >>> d.pop(4) Traceback (most recent call last): File "stdin", line 1, in ? KeyError: 4 >>> d.pop(1) 2 >>> d.pop(1) Traceback (most recent call last): File "stdin", line 1, in ? KeyError: 'pop(): dictionary is empty' >>> d {} >>>
Es gibt auch eine neue Klassenmethode,
dict.fromkeys(iterable, value), die ein Dictionary mit Schlüsseln aus dem bereitgestellten Iterator iterable* erstellt und alle Werte auf value* setzt, standardmäßig aufNone.(Patches beigesteuert von Raymond Hettinger.)
Außerdem akzeptiert der Konstruktor
dict()nun Schlüsselwortargumente, um die Erstellung kleiner Dictionaries zu vereinfachen>>> dict(red=1, blue=2, green=3, black=4) {'blue': 2, 'black': 4, 'green': 3, 'red': 1}
(Beigesteuert von Just van Rossum.)
Die Anweisung
assertprüft nicht mehr das Flag__debug__, so dass Sie Assertions nicht mehr deaktivieren können, indem Sie__debug__zuweisen. Das Ausführen von Python mit der Option-Ogeneriert immer noch Code, der keine Assertions ausführt.Die meisten Typobjekte sind nun aufrufbar, sodass Sie sie zur Erstellung neuer Objekte wie Funktionen, Klassen und Module verwenden können. (Das bedeutet, dass das Modul
newin einer zukünftigen Python-Version veraltet sein könnte, da Sie nun die Typobjekte verwenden können, die im Modultypesverfügbar sind.) Zum Beispiel können Sie ein neues Modulobjekt mit dem folgenden Code erstellen>>> import types >>> m = types.ModuleType('abc','docstring') >>> m <module 'abc' (built-in)> >>> m.__doc__ 'docstring'
Eine neue Warnung,
PendingDeprecationWarning, wurde hinzugefügt, um Funktionen anzuzeigen, die gerade veraltet werden. Die Warnung wird standardmäßig *nicht* ausgegeben. Um nach der Verwendung von Funktionen zu suchen, die in Zukunft veraltet sein werden, geben Sie-Walways::PendingDeprecationWarning::auf der Befehlszeile an oder verwenden Siewarnings.filterwarnings().Der Prozess der Veralterung von zeichenkettenbasierten Ausnahmen, wie in
raise "Error occurred", hat begonnen. Das Auslösen eines Strings löst nunPendingDeprecationWarningaus.Die Verwendung von
Noneals Variablennamen führt nun zu einerSyntaxWarning-Warnung. In einer zukünftigen Python-Version könnteNoneschließlich zu einem Schlüsselwort werden.Die Methode
xreadlines()von Dateiobjekten, die in Python 2.1 eingeführt wurde, ist nicht mehr notwendig, da Dateien nun als eigene Iteratoren fungieren.xreadlines()wurde ursprünglich als schnellere Möglichkeit eingeführt, über alle Zeilen einer Datei zu iterieren, aber jetzt können Sie einfachfor line in file_objschreiben. Dateiobjekte haben auch ein neues schreibgeschütztes Attributencoding, das die für die Datei verwendete Kodierung angibt; an die Datei geschriebene Unicode-Strings werden automatisch mithilfe der angegebenen Kodierung in Bytes konvertiert.Die Method Resolution Order (MRO), die von neuen Klassen verwendet wird, hat sich geändert, obwohl Sie den Unterschied nur bemerken werden, wenn Sie eine wirklich komplizierte Vererbungshierarchie haben. Klassische Klassen sind von dieser Änderung nicht betroffen. Python 2.2 verwendete ursprünglich eine topologische Sortierung der Vorfahren einer Klasse, aber 2.3 verwendet nun den C3-Algorithmus, wie im Paper „A Monotonic Superclass Linearization for Dylan“ beschrieben. Um die Motivation für diese Änderung zu verstehen, lesen Sie den Artikel von Michele Simionato The Python 2.3 Method Resolution Order oder lesen Sie den Thread auf python-dev, beginnend mit der Nachricht unter https://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele Pedroni wies zuerst auf das Problem hin und implementierte auch die Korrektur, indem er den C3-Algorithmus kodierte.
Python führt multithreaded Programme aus, indem es zwischen Threads wechselt, nachdem N Bytecodes ausgeführt wurden. Der Standardwert für N wurde von 10 auf 100 Bytecodes erhöht, was Single-Threaded-Anwendungen durch Reduzierung des Switching-Overheads beschleunigt. Einige multithreaded Anwendungen können eine langsamere Reaktionszeit aufweisen, aber das lässt sich leicht beheben, indem die Grenze mit
sys.setcheckinterval(N)auf eine niedrigere Zahl zurückgesetzt wird. Das Limit kann mit der neuen Funktionsys.getcheckinterval()abgerufen werden.Eine kleine, aber weitreichende Änderung ist, dass die Namen von Erweiterungstypen, die von den in Python enthaltenen Modulen definiert werden, nun das Modul und einen Punkt vor dem Typnamen enthalten. Zum Beispiel erhalten Sie in Python 2.2, wenn Sie einen Socket erstellen und seine
__class__drucken, diese Ausgabe>>> s = socket.socket() >>> s.__class__ <type 'socket'>
In 2.3 erhalten Sie dies
>>> s.__class__ <type '_socket.socket'>
Eine der bemerkten Inkompatibilitäten zwischen alten und neuen Klassen wurde entfernt: Sie können nun die Attribute
__name__und__bases__von neuen Klassen zuweisen. Es gibt einige Einschränkungen für die Zuweisung zu__bases__, die denen für die Zuweisung zu__class__eines Instanz entsprechen.
String-Änderungen¶
Der Operator
inverhält sich für Strings nun anders. Zuvor, bei der Auswertung vonX in Y, wenn X und Y Strings waren, konnte X* nur ein einzelnes Zeichen sein. Das hat sich nun geändert; *X* kann ein String beliebiger Länge sein, undX in YgibtTruezurück, wenn X* ein Substring von *Y* ist. Wenn *X* der leere String ist, ist das Ergebnis immerTrue.>>> 'ab' in 'abcd' True >>> 'ad' in 'abcd' False >>> '' in 'abcd' True
Beachten Sie, dass dies nicht angibt, wo der Substring beginnt; wenn Sie diese Information benötigen, verwenden Sie die String-Methode
find().Die String-Methoden
strip(),lstrip()undrstrip()haben nun ein optionales Argument zur Angabe der zu entfernenden Zeichen. Standardmäßig werden weiterhin alle Whitespace-Zeichen entfernt.>>> ' abc '.strip() 'abc' >>> '><><abc<><><>'.strip('<>') 'abc' >>> '><><abc<><><>\n'.strip('<>') 'abc<><><>\n' >>> u'\u4000\u4001abc\u4000'.strip(u'\u4000') u'\u4001abc' >>>
(Vorgeschlagen von Simon Brunning und implementiert von Walter Dörwald.)
Die String-Methoden
startswith()undendswith()akzeptieren nun negative Zahlen für die Parameter start und end.Eine weitere neue String-Methode ist
zfill(), ursprünglich eine Funktion imstring-Modul.zfill()füllt eine numerische Zeichenkette links mit Nullen auf, bis sie die angegebene Breite erreicht. Beachten Sie, dass der%-Operator immer noch flexibler und leistungsfähiger alszfill()ist.>>> '45'.zfill(4) '0045' >>> '12345'.zfill(4) '12345' >>> 'goofy'.zfill(6) '0goofy'
(Beigesteuert von Walter Dörwald.)
Ein neuer Typobjekt,
basestring, wurde hinzugefügt. Sowohl 8-Bit-Strings als auch Unicode-Strings erben von diesem Typ, sodassisinstance(obj, basestring)für beide Arten von StringsTruezurückgibt. Es handelt sich um einen vollständig abstrakten Typ, sodass keine Instanzen vonbasestringerstellt werden können.Internierte Zeichenketten sind nicht mehr unsterblich und werden nun auf die übliche Weise vom Garbage Collector eingesammelt, wenn die einzige Referenz darauf aus dem internen Dictionary der interierten Zeichenketten stammt. (Implementiert von Oren Tirosh.)
Optimierungen¶
Die Erzeugung von Instanzen von Klassen des neuen Stils wurde erheblich beschleunigt; sie sind nun schneller als klassische Klassen!
Die Methode
sort()von Listenobjekten wurde von Tim Peters umfassend neu geschrieben, und die Implementierung ist erheblich schneller.Die Multiplikation großer langer Ganzzahlen ist dank einer Implementierung der Karatsuba-Multiplikation, einem Algorithmus, der besser skaliert als die O(n^2)-Komplexität, die für den Schulbuch-Multiplikationsalgorithmus erforderlich ist, nun viel schneller. (Ursprünglicher Patch von Christopher A. Craig, und erheblich überarbeitet von Tim Peters.)
Der
SET_LINENO-Opcode ist nun entfernt. Dies kann eine kleine Geschwindigkeitssteigerung bewirken, abhängig von den Eigenheiten Ihres Compilers. Siehe Abschnitt Andere Änderungen und Korrekturen für eine längere Erklärung. (Entfernt von Michael Hudson.)xrange()-Objekte haben nun ihren eigenen Iterator, wasfor i in xrange(n)etwas schneller macht alsfor i in range(n). (Patch von Raymond Hettinger.)Eine Reihe kleinerer Umordnungen wurden in verschiedenen Hotspots vorgenommen, um die Leistung zu verbessern, z. B. durch Inline-Funktionen oder das Entfernen von Code. (Hauptsächlich implementiert von GvR, aber viele Leute haben einzelne Änderungen beigesteuert.)
Das Nettoergebnis der Optimierungen für 2.3 ist, dass Python 2.3 den Pystone-Benchmark etwa 25 % schneller ausführt als Python 2.2.
Neue, verbesserte und veraltete Module¶
Wie üblich hat die Standardbibliothek von Python eine Reihe von Verbesserungen und Fehlerbehebungen erhalten. Hier ist eine Teilliste der bemerkenswertesten Änderungen, alphabetisch nach Modulnamen sortiert. Konsultieren Sie die Datei Misc/NEWS im Quellbaum für eine vollständigere Liste der Änderungen oder durchsuchen Sie die CVS-Protokolle für alle Details.
Das
array-Modul unterstützt nun Arrays von Unicode-Zeichen mit dem Formatierungszeichen'u'. Arrays unterstützen nun auch die Verwendung des Zuweisungsoperators+=zum Hinzufügen des Inhalts eines anderen Arrays und des Zuweisungsoperators*=zum Wiederholen eines Arrays. (Beigesteuert von Jason Orendorff.)Das
bsddb-Modul wurde durch Version 4.1.6 des PyBSDDB-Pakets ersetzt, das eine vollständigere Schnittstelle zu den transaktionalen Funktionen der BerkeleyDB-Bibliothek bietet.Die alte Version des Moduls wurde in
bsddb185umbenannt und wird nicht mehr automatisch erstellt. Sie müssenModules/Setupbearbeiten, um es zu aktivieren. Beachten Sie, dass das neuebsddb-Paket mit dem alten Modul kompatibel sein soll, reichen Sie also bitte Fehler ein, wenn Sie Inkompatibilitäten feststellen. Beim Upgrade auf Python 2.3 müssen Sie, wenn der neue Interpreter mit einer neuen Version der zugrunde liegenden BerkeleyDB-Bibliothek kompiliert wird, fast sicher Ihre Datenbankdateien in die neue Version konvertieren. Dies können Sie ziemlich einfach mit den neuen Skriptendb2pickle.pyundpickle2db.pyerledigen, die Sie im VerzeichnisTools/scriptsder Distribution finden. Wenn Sie bereits das PyBSDDB-Paket verwendet und es alsbsddb3importiert haben, müssen Sie Ihreimport-Anweisungen ändern, um es alsbsddbzu importieren.Das neue Modul
bz2ist eine Schnittstelle zur bzip2-Datenkomprimierungsbibliothek. bzip2-komprimierte Daten sind normalerweise kleiner als entsprechendezlib-komprimierte Daten. (Beigesteuert von Gustavo Niemeyer.)Eine Reihe von Standard-Datums-/Zeit-Typen wurde im neuen Modul
datetimehinzugefügt. Mehr Details finden Sie im folgenden Abschnitt.Die Distutils
Extension-Klasse unterstützt nun ein zusätzliches Konstruktorargument namens depends, um zusätzliche Quelldateien aufzulisten, von denen eine Erweiterung abhängt. Dadurch kann Distutils das Modul neu kompilieren, wenn eine der Abhängigkeitsdateien geändert wird. Wenn beispielsweisesampmodule.cdie Header-Dateisample.heinbindet, würden Sie dasExtension-Objekt wie folgt erstellen:ext = Extension("samp", sources=["sampmodule.c"], depends=["sample.h"])
Das Ändern von
sample.hwürde dann dazu führen, dass das Modul neu kompiliert wird. (Beigesteuert von Jeremy Hylton.)Weitere kleinere Änderungen an Distutils: Es werden nun die Umgebungsvariablen
CC,CFLAGS,CPP,LDFLAGSundCPPFLAGSüberprüft, mit denen die Einstellungen in der Python-Konfiguration überschrieben werden (beigesteuert von Robert Weber).Zuvor durchsuchte das Modul
doctestnur die Docstrings von öffentlichen Methoden und Funktionen nach Testfällen, aber nun werden auch private untersucht. Die FunktionDocTestSuite()erstellt einunittest.TestSuite-Objekt aus einer Reihe vondoctest-Tests.Die neue Funktion
gc.get_referents(object)gibt eine Liste aller Objekte zurück, auf die von object verwiesen wird.Das Modul
getopterhielt eine neue Funktion,gnu_getopt(), die dieselben Argumente wie die bestehende Funktiongetopt()unterstützt, aber den Scanning-Modus im GNU-Stil verwendet. Die bestehende Funktiongetopt()stoppt die Verarbeitung von Optionen, sobald ein Nicht-Options-Argument angetroffen wird, aber im GNU-Stil wird die Verarbeitung fortgesetzt, was bedeutet, dass Optionen und Argumente gemischt werden können. Zum Beispiel:>>> getopt.getopt(['-f', 'filename', 'output', '-v'], 'f:v') ([('-f', 'filename')], ['output', '-v']) >>> getopt.gnu_getopt(['-f', 'filename', 'output', '-v'], 'f:v') ([('-f', 'filename'), ('-v', '')], ['output'])
(Beigesteuert von Peter Åstrand.)
Die Module
grp,pwdundresourcegeben nun erweiterte Tupel zurück.>>> import grp >>> g = grp.getgrnam('amk') >>> g.gr_name, g.gr_gid ('amk', 500)
Das Modul
gzipkann nun Dateien mit mehr als 2 GiB verarbeiten.Das neue Modul
heapqenthält eine Implementierung eines Heap-Warteschlangen-Algorithmus. Ein Heap ist eine arrayähnliche Datenstruktur, die Elemente in einer teilweise sortierten Reihenfolge hält, so dass für jeden Index k gilt:heap[k] <= heap[2*k+1]undheap[k] <= heap[2*k+2]. Dies macht das Entfernen des kleinsten Elements schnell, und das Einfügen eines neuen Elements unter Beibehaltung der Heap-Eigenschaft dauert O(log n). (Siehe https://xlinux.nist.gov/dads//HTML/priorityque.html für weitere Informationen über die Priority-Queue-Datenstruktur.)Das Modul
heapqbietet die Funktionenheappush()undheappop()zum Hinzufügen und Entfernen von Elementen, während die Heap-Eigenschaft über einem anderen veränderlichen Python-Sequenztyp aufrechterhalten wird. Hier ist ein Beispiel, das eine Python-Liste verwendet:>>> import heapq >>> heap = [] >>> for item in [3, 7, 5, 11, 1]: ... heapq.heappush(heap, item) ... >>> heap [1, 3, 5, 11, 7] >>> heapq.heappop(heap) 1 >>> heapq.heappop(heap) 3 >>> heap [5, 7, 11]
(Beigesteuert von Kevin O’Connor.)
Die integrierte Entwicklungsumgebung IDLE wurde unter Verwendung des Codes aus dem IDLEfork-Projekt (https://idlefork.sourceforge.net) aktualisiert. Das bemerkenswerteste Merkmal ist, dass der entwickelte Code nun in einem Subprozess ausgeführt wird, was bedeutet, dass manuelle
reload()-Operationen nicht mehr erforderlich sind. Der Kerncode von IDLE wurde als Paketidlelibin die Standardbibliothek integriert.Das Modul
imaplibunterstützt nun IMAP über SSL. (Beigesteuert von Piers Lauder und Tino Lange.)Das Modul
itertoolsenthält eine Reihe nützlicher Funktionen für die Arbeit mit Iteratoren, inspiriert von verschiedenen Funktionen der Sprachen ML und Haskell. Zum Beispiel gibtitertools.ifilter(predicate, iterator)alle Elemente im Iterator zurück, für die die Funktionpredicate()Truezurückgibt, unditertools.repeat(obj, N)gibtobjN Mal zurück. Es gibt eine Reihe weiterer Funktionen im Modul; siehe die Referenzdokumentation des Pakets für Details. (Beigesteuert von Raymond Hettinger.)Zwei neue Funktionen im Modul
math,degrees(rads)undradians(degs), konvertieren zwischen Radiant und Grad. Andere Funktionen im Modulmathwiemath.sin()undmath.cos()haben immer Eingabewerte in Radiant erfordert. Außerdem wurde ein optionales Argument base zumath.log()hinzugefügt, um die Berechnung von Logarithmen zu Basen außereund10zu erleichtern. (Beigesteuert von Raymond Hettinger.)Mehrere neue POSIX-Funktionen (
getpgid(),killpg(),lchown(),loadavg(),major(),makedev(),minor()undmknod()) wurden dem Modulposixhinzugefügt, das dem Moduloszugrunde liegt. (Beigesteuert von Gustavo Niemeyer, Geert Jansen und Denis S. Otkidach.)Im Modul
oskönnen die Funktionen der*stat()-Familie nun Bruchteile von Sekunden in einem Zeitstempel melden. Solche Zeitstempel werden als Gleitkommazahlen dargestellt, ähnlich dem Wert, der vontime.time()zurückgegeben wird.Während der Tests wurde festgestellt, dass einige Anwendungen brechen, wenn Zeitstempel Gleitkommazahlen sind. Aus Kompatibilitätsgründen werden bei Verwendung der Tupel-Schnittstelle von
stat_resultdie Zeitstempel als Ganzzahlen dargestellt. Bei Verwendung benannter Felder (ein Merkmal, das erstmals in Python 2.2 eingeführt wurde) werden Zeitstempel weiterhin als Ganzzahlen dargestellt, es sei denn,os.stat_float_times()wird aufgerufen, um Gleitkomma-Rückgabewerte zu aktivieren.>>> os.stat("/tmp").st_mtime 1034791200 >>> os.stat_float_times(True) >>> os.stat("/tmp").st_mtime 1034791200.6335014
In Python 2.4 wird die Standardeinstellung auf die Rückgabe von Gleitkommazahlen umgestellt.
Anwendungsentwickler sollten dieses Merkmal nur aktivieren, wenn alle ihre Bibliotheken ordnungsgemäß funktionieren, wenn sie mit Gleitkomma-Zeitstempeln konfrontiert werden, oder wenn sie die Tupel-API verwenden. Wenn es verwendet wird, sollte das Merkmal auf Anwendungsebene aktiviert werden, anstatt zu versuchen, es pro Nutzung zu aktivieren.
Das Modul
optparseenthält einen neuen Parser für Befehlszeilenargumente, der Optionswerte in einen bestimmten Python-Typ konvertieren kann und automatisch eine Nutzungsnachricht generiert. Mehr Details finden Sie im folgenden Abschnitt.Das alte und nie dokumentierte Modul
linuxaudiodevwurde veraltet, und eine neue Version namensossaudiodevwurde hinzugefügt. Das Modul wurde umbenannt, da die OSS-Soundtreiber auf anderen Plattformen als Linux verwendet werden können und die Schnittstelle auch auf verschiedene Weise aufgeräumt und aktualisiert wurde. (Beigesteuert von Greg Ward und Nicholas FitzRoy-Dale.)Das neue Modul
platformenthält eine Reihe von Funktionen, die versuchen, verschiedene Eigenschaften der Plattform zu ermitteln, auf der Sie gerade arbeiten. Es gibt Funktionen zum Abrufen der Architektur, des CPU-Typs, der Windows-Betriebssystemversion und sogar der Linux-Distribution-Version. (Beigesteuert von Marc-André Lemburg.)Die von den Parser-Objekten im Modul
pyexpatbereitgestellten können nun optional Zeichendaten puffern, was zu weniger Aufrufen Ihrer Zeichendaten-Handler und damit zu einer schnelleren Leistung führt. Das Setzen des Attributsbuffer_textdes Parser-Objekts aufTrueaktiviert das Puffern.Die Funktion
sample(population, k)wurde dem Modulrandomhinzugefügt. population ist eine Sequenz oder einxrange-Objekt, das die Elemente einer Population enthält, undsample()wählt k Elemente aus der Population ohne Ersetzung aus. k kann jeden Wert bis zulen(population)haben. Zum Beispiel:>>> days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'St', 'Sn'] >>> random.sample(days, 3) # Choose 3 elements ['St', 'Sn', 'Th'] >>> random.sample(days, 7) # Choose 7 elements ['Tu', 'Th', 'Mo', 'We', 'St', 'Fr', 'Sn'] >>> random.sample(days, 7) # Choose 7 again ['We', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th'] >>> random.sample(days, 8) # Can't choose eight Traceback (most recent call last): File "<stdin>", line 1, in ? File "random.py", line 414, in sample raise ValueError, "sample larger than population" ValueError: sample larger than population >>> random.sample(xrange(1,10000,2), 10) # Choose ten odd nos. under 10000 [3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]
Das Modul
randomverwendet nun einen neuen Algorithmus, den Mersenne Twister, implementiert in C. Er ist schneller und gründlicher untersucht als der vorherige Algorithmus.(Alle Änderungen wurden von Raymond Hettinger beigesteuert.)
Das Modul
readlineerhielt ebenfalls eine Reihe neuer Funktionen:get_history_item(),get_current_history_length()undredisplay().Die Module
rexecundBastionwurden als veraltet deklariert, und Versuche, sie zu importieren, führen zu einemRuntimeError. Klassen des neuen Stils bieten neue Möglichkeiten, aus der eingeschränkten Ausführungsumgebung vonrexecauszubrechen, und niemand hat Interesse oder Zeit, sie zu reparieren. Wenn Sie Anwendungen haben, dierexecverwenden, schreiben Sie sie neu, um etwas anderes zu verwenden.(Wenn Sie bei Python 2.2 oder 2.1 bleiben, werden Ihre Anwendungen nicht sicherer, da in diesen Versionen bekannte Fehler im Modul
rexecvorhanden sind. Um es zu wiederholen: Wenn Sierexecverwenden, hören Sie sofort damit auf!)Das Modul
rotorwurde veraltet, da der Algorithmus, den es zur Verschlüsselung verwendet, nicht als sicher gilt. Wenn Sie Verschlüsselung benötigen, verwenden Sie eines der verschiedenen AES-Python-Module, die separat erhältlich sind.Das Modul
shutilerhielt eine Funktionmove(src, dest), die eine Datei oder ein Verzeichnis rekursiv an einen neuen Ort verschiebt.Unterstützung für erweiterte POSIX-Signalbehandlung wurde zum Modul
signalhinzugefügt, dann aber wieder entfernt, da es sich als unmöglich erwies, sie plattformübergreifend zuverlässig zum Laufen zu bringen.Das Modul
socketunterstützt nun Timeouts. Sie können die Methodesettimeout(t)auf einem Socket-Objekt aufrufen, um einen Timeout von t Sekunden festzulegen. Nachfolgende Socket-Operationen, die länger als t Sekunden dauern, werden abgebrochen und lösen eine Ausnahmesocket.timeoutaus.Die ursprüngliche Timeout-Implementierung stammte von Tim O’Malley. Michael Gilfix integrierte sie in das Python
socket-Modul und begleitete sie durch eine lange Überprüfung. Nachdem der Code eingecheckt war, schrieb Guido van Rossum Teile davon neu. (Dies ist ein gutes Beispiel für einen kollaborativen Entwicklungsprozess.)Unter Windows wird das Modul
socketnun mit Unterstützung für Secure Sockets Layer (SSL) ausgeliefert.Der Wert des C
PYTHON_API_VERSION-Makros wird nun auf Python-Ebene alssys.api_versionverfügbar gemacht. Die aktuelle Ausnahme kann durch Aufruf der neuen Funktionsys.exc_clear()gelöscht werden.Das neue Modul
tarfileermöglicht das Lesen und Schreiben von Archivdateien im tar-Format. (Beigetragen von Lars Gustäbel.)Das neue Modul
textwrapenthält Funktionen zum Umbrechen von Zeichenketten, die Textabsätze enthalten. Die Funktionwrap(text, width)nimmt eine Zeichenkette und gibt eine Liste zurück, die den in Zeilen mit maximal der gewählten Breite aufgeteilten Text enthält. Die Funktionfill(text, width)gibt eine einzelne Zeichenkette zurück, die neu formatiert wurde, um in Zeilen zu passen, die nicht länger als die gewählte Breite sind. (Wie Sie sich denken können, basiertfill()aufwrap(). Zum Beispiel>>> import textwrap >>> paragraph = "Not a whit, we defy augury: ... more text ..." >>> textwrap.wrap(paragraph, 60) ["Not a whit, we defy augury: there's a special providence in", "the fall of a sparrow. If it be now, 'tis not to come; if it", ...] >>> print textwrap.fill(paragraph, 35) Not a whit, we defy augury: there's a special providence in the fall of a sparrow. If it be now, 'tis not to come; if it be not to come, it will be now; if it be not now, yet it will come: the readiness is all. >>>
Das Modul enthält auch eine Klasse
TextWrapper, die tatsächlich die Strategie für den Textumbruch implementiert. Sowohl die KlasseTextWrapperals auch die Funktionenwrap()undfill()unterstützen eine Reihe zusätzlicher Schlüsselwortargumente zur Feinabstimmung der Formatierung; Details finden Sie in der Dokumentation des Moduls. (Beigetragen von Greg Ward.)Die Module
threadundthreadinghaben jetzt Begleitmodule,dummy_threadunddummy_threading, die eine Nichtstun-Implementierung der Schnittstelle desthread-Moduls für Plattformen bereitstellen, auf denen Threads nicht unterstützt werden. Die Absicht ist, Thread-fähige Module (solche, die *nicht* auf Threads angewiesen sind, um zu laufen) zu vereinfachen, indem der folgende Code am Anfang platziert wirdtry: import threading as _threading except ImportError: import dummy_threading as _threading
In diesem Beispiel wird
_threadingals Modulname verwendet, um deutlich zu machen, dass das verwendete Modul nicht unbedingt das tatsächlichethreading-Modul ist. Der Code kann Funktionen aufrufen und Klassen in_threadingverwenden, unabhängig davon, ob Threads unterstützt werden oder nicht, wodurch eineif-Anweisung vermieden wird und der Code etwas klarer wird. Dieses Modul macht multithreaded Code nicht magisch ohne Threads ausführbar; Code, der darauf wartet, dass ein anderer Thread zurückkehrt oder etwas tut, wird einfach für immer hängen bleiben.Die Funktion
strptime()des Modulstimewar lange Zeit ein Ärgernis, da sie die Implementierung vonstrptime()der Plattform-C-Bibliothek verwendet und verschiedene Plattformen manchmal seltsame Fehler haben. Brett Cannon trug eine portable Implementierung bei, die in reinem Python geschrieben ist und auf allen Plattformen identisch funktionieren sollte.Das neue Modul
timeithilft bei der Messung der Ausführungszeit von Python-Code-Snippets. Die Dateitimeit.pykann direkt von der Kommandozeile ausgeführt werden, oder die KlasseTimerdes Moduls kann importiert und direkt verwendet werden. Hier ist ein kurzes Beispiel, das ermittelt, ob die Konvertierung eines 8-Bit-Strings in Unicode durch Anhängen eines leeren Unicode-Strings daran oder durch Verwendung der Funktionunicode()schneller istimport timeit timer1 = timeit.Timer('unicode("abc")') timer2 = timeit.Timer('"abc" + u""') # Run three trials print timer1.repeat(repeat=3, number=100000) print timer2.repeat(repeat=3, number=100000) # On my laptop this outputs: # [0.36831796169281006, 0.37441694736480713, 0.35304892063140869] # [0.17574405670166016, 0.18193507194519043, 0.17565798759460449]
Das Modul
Tixhat verschiedene Fehlerkorrekturen und Aktualisierungen für die aktuelle Version des Tix-Pakets erhalten.Das Modul
Tkinterfunktioniert jetzt mit einer Thread-fähigen Version von Tcl. Das Threading-Modell von Tcl verlangt, dass Widgets nur von dem Thread aus angesprochen werden dürfen, in dem sie erstellt wurden; Zugriffe von einem anderen Thread können dazu führen, dass Tcl abstürzt. Für bestimmte Tcl-Schnittstellen vermeidetTkinterdies jetzt automatisch, wenn ein Widget von einem anderen Thread aus angesprochen wird, indem ein Befehl marshalt, an den richtigen Thread übergeben und auf die Ergebnisse gewartet wird. Andere Schnittstellen können nicht automatisch gehandhabt werden, aberTkinterlöst jetzt eine Ausnahme bei einem solchen Zugriff aus, so dass Sie zumindest von dem Problem erfahren. Weitere Erläuterungen zu dieser Änderung finden Sie unter https://mail.python.org/pipermail/python-dev/2002-December/031107.html. (Implementiert von Martin von Löwis.)Das Aufrufen von Tcl-Methoden über
_tkintergibt nicht mehr nur Zeichenketten zurück. Stattdessen werden, wenn Tcl andere Objekte zurückgibt, diese in ihr Python-Äquivalent konvertiert, falls eines existiert, oder mit einem_tkinter.Tcl_Obj-Objekt umschlossen, falls kein Python-Äquivalent existiert. Dieses Verhalten kann über die Methodewantobjects()vontkapp-Objekten gesteuert werden.Wenn
_tkinterüber das ModulTkinterverwendet wird (wie die meisten Tkinter-Anwendungen), ist diese Funktion immer aktiviert. Sie sollte keine Kompatibilitätsprobleme verursachen, da Tkinter Zeichenketten-Ergebnisse, wo möglich, immer in Python-Typen konvertieren würde.Sollten Inkompatibilitäten auftreten, kann das alte Verhalten wiederhergestellt werden, indem die Variable
wantobjectsim ModulTkinterauf false gesetzt wird, bevor das erstetkapp-Objekt erstellt wird.import Tkinter Tkinter.wantobjects = 0
Jegliche durch diese Änderung verursachten Probleme sollten als Fehler gemeldet werden.
Das Modul
UserDicthat eine neue KlasseDictMixin, die alle Dictionary-Methoden für Klassen definiert, die bereits eine minimale Mapping-Schnittstelle besitzen. Dies vereinfacht die Erstellung von Klassen, die als Ersatz für Dictionaries dienen sollen, erheblich, wie z.B. die Klassen im Modulshelve.Das Hinzufügen des Mix-ins als Oberklasse bietet die vollständige Dictionary-Schnittstelle, wann immer die Klasse
__getitem__(),__setitem__(),__delitem__()undkeys()definiert. Zum Beispiel>>> import UserDict >>> class SeqDict(UserDict.DictMixin): ... """Dictionary lookalike implemented with lists.""" ... def __init__(self): ... self.keylist = [] ... self.valuelist = [] ... def __getitem__(self, key): ... try: ... i = self.keylist.index(key) ... except ValueError: ... raise KeyError ... return self.valuelist[i] ... def __setitem__(self, key, value): ... try: ... i = self.keylist.index(key) ... self.valuelist[i] = value ... except ValueError: ... self.keylist.append(key) ... self.valuelist.append(value) ... def __delitem__(self, key): ... try: ... i = self.keylist.index(key) ... except ValueError: ... raise KeyError ... self.keylist.pop(i) ... self.valuelist.pop(i) ... def keys(self): ... return list(self.keylist) ... >>> s = SeqDict() >>> dir(s) # See that other dictionary methods are implemented ['__cmp__', '__contains__', '__delitem__', '__doc__', '__getitem__', '__init__', '__iter__', '__len__', '__module__', '__repr__', '__setitem__', 'clear', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keylist', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'valuelist', 'values']
(Beigetragen von Raymond Hettinger.)
Die DOM-Implementierung in
xml.dom.minidomkann nun XML-Ausgaben in einer bestimmten Kodierung generieren, indem ein optionales Kodierungsargument an die Methodentoxml()undtoprettyxml()von DOM-Knoten übergeben wird.Das Modul
xmlrpclibunterstützt nun eine XML-RPC-Erweiterung für die Handhabung von Nil-Datenwerten wie PythonsNone. Nil-Werte werden beim Entpacken einer XML-RPC-Antwort immer unterstützt. Um Anfragen mitNonezu generieren, müssen Sie für den Parameter allow_none einen wahren Wert angeben, wenn Sie eine Instanz vonMarshallererstellen.Das neue Modul
DocXMLRPCServerermöglicht das Schreiben von selbstdokumentierenden XML-RPC-Servern. Führen Sie es im Demo-Modus (als Programm) aus, um es in Aktion zu sehen. Das Zeigen des Webbrowsers auf den RPC-Server erzeugt pydoc-ähnliche Dokumentation; das Zeigen von xmlrpclib auf den Server ermöglicht die Aufrufung der tatsächlichen Methoden. (Beigetragen von Brian Quinlan.)Unterstützung für internationalisierte Domainnamen (RFCs 3454, 3490, 3491 und 3492) wurde hinzugefügt. Die Kodierung "idna" kann verwendet werden, um zwischen einem Unicode-Domainnamen und der ASCII-kompatiblen Kodierung (ACE) dieses Namens zu konvertieren.
>{}>{}> u"www.Alliancefrançaise.nu".encode("idna") 'www.xn--alliancefranaise-npb.nu'
Das Modul
socketwurde ebenfalls erweitert, um Unicode-Hostnamen transparent in die ACE-Version zu konvertieren, bevor sie an die C-Bibliothek übergeben werden. Module, die mit Hostnamen arbeiten, wie z.B.httplibundftplib) unterstützen ebenfalls Unicode-Hostnamen;httplibsendet auch HTTPHost-Header unter Verwendung der ACE-Version des Domainnamens.urllibunterstützt Unicode-URLs mit Nicht-ASCII-Hostnamen, solange derpath-Teil der URL nur ASCII enthält.Zur Implementierung dieser Änderung wurden das Modul
stringprep, das Werkzeugmkstringprepund die Kodierungpunycodehinzugefügt.
Datums-/Zeit-Typ¶
Datums- und Zeittypen, die für die Darstellung von Zeitstempeln geeignet sind, wurden als Modul datetime hinzugefügt. Die Typen unterstützen keine verschiedenen Kalender oder viele ausgefallene Funktionen und bleiben bei den Grundlagen der Zeitdarstellung.
Die drei Haupttypen sind: date, das Tag, Monat und Jahr darstellt; time, bestehend aus Stunde, Minute und Sekunde; und datetime, das alle Attribute sowohl von date als auch von time enthält. Es gibt auch eine Klasse timedelta, die Differenzen zwischen zwei Zeitpunkten darstellt, und die Zeitzonenlogik wird durch Klassen implementiert, die von der abstrakten Klasse tzinfo erben.
Sie können Instanzen von date und time erstellen, indem Sie entweder Schlüsselwortargumente an den entsprechenden Konstruktor übergeben, z.B. datetime.date(year=1972, month=10, day=15), oder indem Sie eine von mehreren Klassenmethoden verwenden. Zum Beispiel gibt die Klassenmethode today() das aktuelle lokale Datum zurück.
Nach der Erstellung sind Instanzen der Datums-/Zeitklassen alle unveränderlich. Es gibt eine Reihe von Methoden zur Erzeugung formatierter Zeichenketten aus Objekten
>>> import datetime
>>> now = datetime.datetime.now()
>>> now.isoformat()
'2002-12-30T21:27:03.994956'
>>> now.ctime() # Only available on date, datetime
'Mon Dec 30 21:27:03 2002'
>>> now.strftime('%Y %d %b')
'2002 30 Dec'
Die Methode replace() ermöglicht die Änderung eines oder mehrerer Felder einer Instanz von date oder datetime und gibt eine neue Instanz zurück
>>> d = datetime.datetime.now()
>>> d
datetime.datetime(2002, 12, 30, 22, 15, 38, 827738)
>>> d.replace(year=2001, hour = 12)
datetime.datetime(2001, 12, 30, 12, 15, 38, 827738)
>>>
Instanzen können verglichen, gehasht und in Zeichenketten umgewandelt werden (das Ergebnis ist dasselbe wie bei isoformat()). Instanzen von date und datetime können voneinander subtrahiert und zu Instanzen von timedelta addiert werden. Das größte fehlende Feature ist, dass es keine Standardbibliothek-Unterstützung für das Parsen von Zeichenketten und das Zurückgeben eines date- oder datetime-Objekts gibt.
Weitere Informationen finden Sie in der Referenzdokumentation des Moduls. (Beigetragen von Tim Peters.)
Das optparse-Modul¶
Das Modul getopt bietet eine einfache Analyse von Kommandozeilenargumenten. Das neue Modul optparse (ursprünglich Optik genannt) bietet eine elaboriertere Analyse von Kommandozeilen, die den Unix-Konventionen folgt, automatisch die Ausgabe für --help erstellt und unterschiedliche Aktionen für unterschiedliche Optionen ausführen kann.
Sie beginnen, indem Sie eine Instanz von OptionParser erstellen und dem Programm mitteilen, welche Optionen es hat.
import sys
from optparse import OptionParser
op = OptionParser()
op.add_option('-i', '--input',
action='store', type='string', dest='input',
help='set input filename')
op.add_option('-l', '--length',
action='store', type='int', dest='length',
help='set maximum length of output')
Die Analyse einer Kommandozeile erfolgt dann durch Aufrufen der Methode parse_args().
options, args = op.parse_args(sys.argv[1:])
print options
print args
Dies gibt ein Objekt zurück, das alle Optionswerte und eine Liste von Zeichenketten mit den verbleibenden Argumenten enthält.
Das Aufrufen des Skripts mit den verschiedenen Argumenten funktioniert nun wie erwartet. Beachten Sie, dass das Längenargument automatisch in eine Ganzzahl konvertiert wird.
$ ./python opt.py -i data arg1
<Values at 0x400cad4c: {'input': 'data', 'length': None}>
['arg1']
$ ./python opt.py --input=data --length=4
<Values at 0x400cad2c: {'input': 'data', 'length': 4}>
[]
$
Die Hilfenachrichte wird automatisch für Sie generiert
$ ./python opt.py --help
usage: opt.py [options]
options:
-h, --help show this help message and exit
-iINPUT, --input=INPUT
set input filename
-lLENGTH, --length=LENGTH
set maximum length of output
$
Weitere Einzelheiten finden Sie in der Dokumentation des Moduls.
Optik wurde von Greg Ward geschrieben, mit Vorschlägen von den Lesern der Getopt SIG.
Pymalloc: Ein spezialisierter Objektallokator¶
Pymalloc, ein spezialisierter Objektallokator, der von Vladimir Marangozov geschrieben wurde, war eine Funktion, die Python 2.1 hinzugefügt wurde. Pymalloc soll schneller sein als das System malloc() und einen geringeren Speicheroverhead für typische Allokationsmuster von Python-Programmen haben. Der Allokator verwendet die C-Funktion malloc(), um große Speicherpools zu erhalten, und erfüllt dann kleinere Speicheranforderungen aus diesen Pools.
In 2.1 und 2.2 war pymalloc eine experimentelle Funktion und nicht standardmäßig aktiviert; Sie mussten es beim Kompilieren von Python explizit aktivieren, indem Sie die Option --with-pymalloc an das configure-Skript übergaben. In 2.3 wurde pymalloc weiter verbessert und ist nun standardmäßig aktiviert; Sie müssen --without-pymalloc angeben, um es zu deaktivieren.
Diese Änderung ist für in Python geschriebenen Code transparent; pymalloc kann jedoch Fehler in C-Erweiterungen aufdecken. Autoren von C-Erweiterungsmodulen sollten ihren Code mit aktiviertem pymalloc testen, da fehlerhafter Code zur Laufzeit zu Core-Dumps führen kann.
Ein besonders häufiger Fehler verursacht Probleme. Es gibt eine Reihe von Speicherallokationsfunktionen in Pythons C-API, die bisher nur Aliase für die malloc() und free() der C-Bibliothek waren, was bedeutet, dass der Fehler nicht bemerkbar war, wenn Sie versehentlich inkompatible Funktionen aufriefen. Wenn der Objektallokator aktiviert ist, sind diese Funktionen keine Aliase mehr für malloc() und free(), und das Aufrufen der falschen Funktion zum Freigeben von Speicher kann zu einem Core-Dump führen. Zum Beispiel muss Speicher, der mit PyObject_Malloc() allokiert wurde, mit PyObject_Free() freigegeben werden, nicht mit free(). Einige mit Python ausgelieferte Module waren davon betroffen und mussten korrigiert werden; zweifellos gibt es weitere Drittanbieter-Module, die das gleiche Problem haben werden.
Als Teil dieser Änderung wurden die verwirrenden Mehrfachschnittstellen für die Speicherallokation auf zwei API-Familien konsolidiert. Speicher, der mit einer Familie allokiert wurde, darf nicht mit Funktionen aus der anderen Familie manipuliert werden. Es gibt eine Familie für die Allokation von Speicherblöcken und eine weitere Familie von Funktionen speziell für die Allokation von Python-Objekten.
Zum Allokieren und Freigeben eines nicht unterscheidbaren Speicherblocks verwenden Sie die Familie "raw memory":
PyMem_Malloc(),PyMem_Realloc()undPyMem_Free().Die Familie "object memory" ist die Schnittstelle zur oben beschriebenen pymalloc-Einrichtung und ist auf eine große Anzahl von "kleinen" Allokationen ausgerichtet:
PyObject_Malloc(),PyObject_Realloc()undPyObject_Free().Zum Allokieren und Freigeben von Python-Objekten verwenden Sie die Familie "object"
PyObject_New,PyObject_NewVarundPyObject_Del().
Dank vieler Arbeit von Tim Peters bietet pymalloc in 2.3 auch Debugging-Funktionen zur Erfassung von Speicherüberschreibungen und doppelten Freigaben sowohl in Erweiterungsmodulen als auch im Interpreter selbst. Um diese Unterstützung zu aktivieren, kompilieren Sie eine Debug-Version des Python-Interpreters, indem Sie configure mit --with-pydebug ausführen.
Um Erweiterungsschreiber zu unterstützen, wird eine Header-Datei Misc/pymemcompat.h mit dem Quellcode von Python 2.3 ausgeliefert, die es Python-Erweiterungen ermöglicht, die 2.3-Schnittstellen zur Speicherallokation zu verwenden, während sie gegen jede Version von Python seit 1.5.2 kompiliert werden. Sie müssten die Datei aus der Python-Quellcodeverteilung kopieren und mit dem Quellcode Ihrer Erweiterung bündeln.
Siehe auch
- https://hg.python.org/cpython/file/default/Objects/obmalloc.c
Für die vollständigen Details der pymalloc-Implementierung siehe die Kommentare oben in der Datei
Objects/obmalloc.cim Python-Quellcode. Der obige Link verweist auf die Datei im SVN-Browser von python.org.
Build- und C-API-Änderungen¶
Änderungen am Build-Prozess von Python und an der C-API umfassen
Die vom Garbage Collector verwendete Zykluserkennungs-Implementierung hat sich als stabil erwiesen, so dass sie nun obligatorisch ist. Sie können Python nicht mehr ohne sie kompilieren und die Option
--with-cycle-gcfür configure wurde entfernt.Python kann nun optional als Shared Library (
libpython2.3.so) erstellt werden, indem--enable-sharedbeim Ausführen des configure-Skripts von Python angegeben wird. (Beigetragen von Ondrej Palkovsky.)Die Makros
DL_EXPORTundDL_IMPORTsind nun veraltet. Initialisierungsfunktionen für Python-Erweiterungsmodule sollten nun mit dem neuen MakroPyMODINIT_FUNCdeklariert werden, während der Python-Kern im Allgemeinen die MakrosPyAPI_FUNCundPyAPI_DATAverwenden wird.Der Interpreter kann ohne Docstrings für die eingebauten Funktionen und Module kompiliert werden, indem
--without-doc-stringsan das configure-Skript übergeben wird. Dies macht die ausführbare Python-Datei etwa 10% kleiner, bedeutet aber auch, dass Sie keine Hilfe für Pythons eingebaute Funktionen erhalten können. (Beigetragen von Gustavo Niemeyer.)Das Makro
PyArg_NoArgs()ist nun veraltet, und Code, der es verwendet, sollte geändert werden. Für Python 2.2 und höher kann die Methodendefinitionstabelle das FlagMETH_NOARGSangeben, was signalisiert, dass keine Argumente vorhanden sind, und die Argumentenprüfung kann dann entfernt werden. Wenn Kompatibilität mit Versionen vor 2.2 von Python wichtig ist, könnte der Code stattdessenPyArg_ParseTuple(args, "")verwenden, aber dies ist langsamer als die Verwendung vonMETH_NOARGS.PyArg_ParseTuple()akzeptiert neue Formatzeichen für verschiedene Größen von vorzeichenlosen Ganzzahlen:Bfür unsigned char,Hfür unsigned short int,Ifür unsigned int undKfür unsigned long long.Eine neue Funktion,
PyObject_DelItemString(mapping, char *key), wurde als Kurzform fürPyObject_DelItem(mapping, PyString_New(key))hinzugefügt.Datei-Objekte verwalten ihren internen Zeichenkettenpuffer nun anders, indem sie ihn bei Bedarf exponentiell vergrößern. Dies führt dazu, dass die Benchmark-Tests in
Lib/test/test_bufio.pyerheblich beschleunigt werden (von 57 Sekunden auf 1,7 Sekunden, laut einer Messung).Es ist nun möglich, Klassen- und statische Methoden für einen C-Erweiterungstyp zu definieren, indem die Flags
METH_CLASSoderMETH_STATICin derPyMethodDef-Struktur einer Methode gesetzt werden.Python enthält nun eine Kopie des Quellcodes des Expat XML-Parsers, wodurch jede Abhängigkeit von einer Systemversion oder lokalen Installation von Expat entfällt.
Wenn Sie Typ-Objekte in Ihrer Erweiterung dynamisch allokieren, sollten Sie sich über eine Änderung der Regeln bezüglich der Attribute
__module__und__name__im Klaren sein. Zusammenfassend lässt sich sagen, dass Sie sicherstellen möchten, dass das Dictionary des Typs einen Schlüssel'__module__'enthält; das Benennen des Modulteils des Typnamens bis zum letzten Punkt hat nicht mehr den gewünschten Effekt. Weitere Details finden Sie in der API-Referenzdokumentation oder im Quellcode.
Port-spezifische Änderungen¶
Die Unterstützung für eine Portierung auf IBMs OS/2 unter Verwendung der EMX-Laufzeitumgebung wurde in den Haupt-Python-Quellbaum integriert. EMX ist eine POSIX-Emulationsschicht über den OS/2-System-APIs. Der Python-Port für EMX versucht, alle von der EMX-Laufzeitumgebung bereitgestellten POSIX-ähnlichen Fähigkeiten zu unterstützen, und ist damit größtenteils erfolgreich; fork() und fcntl() sind durch die Einschränkungen der zugrunde liegenden Emulationsschicht eingeschränkt. Der Standard-OS/2-Port, der den Visual Age Compiler von IBM verwendet, unterstützte ebenfalls die semantisch fallempfindlichen Importe als Teil der Integration des EMX-Ports in CVS. (Beigetragen von Andrew MacIntyre.)
Auf MacOS wurden die meisten Toolbox-Module schwach verlinkt, um die Abwärtskompatibilität zu verbessern. Das bedeutet, dass Module nicht mehr fehlschlagen, wenn eine einzelne Routine in der aktuellen Betriebssystemversion fehlt. Stattdessen löst der Aufruf der fehlenden Routine eine Ausnahme aus. (Beigetragen von Jack Jansen.)
Die RPM-Spec-Dateien, die sich im Verzeichnis Misc/RPM/ in der Python-Quellcode-Distribution befinden, wurden für 2.3 aktualisiert. (Beigetragen von Sean Reifschneider.)
Weitere neue Plattformen, die jetzt von Python unterstützt werden, sind AtheOS (http://www.atheos.cx/), GNU/Hurd und OpenVMS.
Andere Änderungen und Korrekturen¶
Wie üblich gab es eine Reihe weiterer Verbesserungen und Fehlerbehebungen, die über den Quellcode-Baum verteilt waren. Eine Suche in den CVS-Änderungsprotokollen ergab, dass zwischen Python 2.2 und 2.3 523 Patches angewendet und 514 Fehler behoben wurden. Beide Zahlen sind wahrscheinlich Unterschätzungen.
Einige der bemerkenswerteren Änderungen sind:
Wenn die Umgebungsvariable
PYTHONINSPECTgesetzt ist, wird der Python-Interpreter nach der Ausführung eines Python-Programms in die interaktive Eingabeaufforderung wechseln, als ob Python mit der Option-iaufgerufen worden wäre. Die Umgebungsvariable kann gesetzt werden, bevor der Python-Interpreter ausgeführt wird, oder sie kann vom Python-Programm als Teil seiner Ausführung gesetzt werden.Das Skript
regrtest.pybietet jetzt eine Möglichkeit, „alle Ressourcen außer foo“ zuzulassen. Ein Ressourcenname, der an die Option-uübergeben wird, kann nun ein Minuszeichen ('-') vorangestellt bekommen, um „diese Ressource entfernen“ zu bedeuten. Zum Beispiel könnte die Option '-uall,-bsddb' verwendet werden, um die Nutzung aller Ressourcen außerbsddbzu aktivieren.Die Werkzeuge, die zum Erstellen der Dokumentation verwendet werden, funktionieren jetzt sowohl unter Cygwin als auch unter Unix.
Der
SET_LINENOOpcode wurde entfernt. Früher war dieser Opcode erforderlich, um Zeilennummern in Tracebacks zu erzeugen und Trace-Funktionen zu unterstützen (z. B. fürpdb). Seit Python 1.5 werden die Zeilennummern in Tracebacks mit einem anderen Mechanismus berechnet, der mit „python -O“ funktioniert. Für Python 2.3 implementierte Michael Hudson ein ähnliches Schema, um zu bestimmen, wann die Trace-Funktion aufgerufen werden soll, wodurch die Notwendigkeit vonSET_LINENOvollständig entfiel.Es wäre schwierig, einen daraus resultierenden Unterschied im Python-Code zu erkennen, abgesehen von einer leichten Beschleunigung, wenn Python ohne
-Oausgeführt wird.C-Erweiterungen, die auf das Feld
f_linenovon Frame-Objekten zugreifen, sollten stattdessenPyCode_Addr2Line(f->f_code, f->f_lasti)aufrufen. Dies hat den zusätzlichen Effekt, dass der Code auch unter „python -O“ in früheren Python-Versionen wie gewünscht funktioniert.Eine nette neue Funktion ist, dass Trace-Funktionen jetzt dem Attribut
f_linenovon Frame-Objekten Werte zuweisen können, wodurch die als nächstes auszuführende Zeile geändert wird. Dempdb-Debugger wurde einjump-Befehl hinzugefügt, der diese neue Funktion nutzt. (Implementiert von Richie Hindle.)
Portierung auf Python 2.3¶
Dieser Abschnitt listet die zuvor beschriebenen Änderungen auf, die Änderungen an Ihrem Code erfordern könnten.
yieldist jetzt immer ein Schlüsselwort; wenn es in Ihrem Code als Variablennamen verwendet wird, muss ein anderer Name gewählt werden.Für die Zeichenketten X und Y funktioniert
X in Yjetzt auch dann, wenn X mehr als ein Zeichen lang ist.Der Typkonstruktor
int()gibt jetzt eine lange Ganzzahl zurück, anstatt eineOverflowErrorauszulösen, wenn eine Zeichenkette oder eine Gleitkommazahl zu groß ist, um in eine Ganzzahl zu passen.Wenn Sie Unicode-Zeichenketten haben, die 8-Bit-Zeichen enthalten, müssen Sie die Kodierung der Datei (UTF-8, Latin-1 oder eine andere) deklarieren, indem Sie einen Kommentar am Anfang der Datei hinzufügen. Weitere Informationen finden Sie im Abschnitt PEP 263: Source Code Encodings.
Der Aufruf von Tcl-Methoden über
_tkintergibt nicht mehr nur Zeichenketten zurück. Wenn Tcl andere Objekte zurückgibt, werden diese in ihr Python-Äquivalent umgewandelt, falls eines existiert, oder mit einem_tkinter.Tcl_Obj-Objekt umschlossen, wenn kein Python-Äquivalent existiert.Große Oktal- und Hexadezimal-Literale wie
0xfffffffflösen jetzt eineFutureWarningaus. Derzeit werden sie als 32-Bit-Zahlen gespeichert und ergeben einen negativen Wert, aber in Python 2.4 werden sie zu positiven langen Ganzzahlen.Es gibt einige Möglichkeiten, diese Warnung zu beheben. Wenn Sie wirklich eine positive Zahl benötigen, fügen Sie einfach ein
Lam Ende des Literals hinzu. Wenn Sie versuchen, eine 32-Bit-Ganzzahl mit gesetzten niedrigen Bits zu erhalten und zuvor einen Ausdruck wie~(1 << 31)verwendet haben, ist es wahrscheinlich am klarsten, mit allen gesetzten Bits zu beginnen und die gewünschten oberen Bits zu löschen. Um zum Beispiel nur das oberste Bit (Bit 31) zu löschen, könnten Sie0xffffffffL &~(1L<<31)schreiben.Sie können keine Assertionen mehr deaktivieren, indem Sie
__debug__zuweisen.Die Distutils-Funktion
setup()hat verschiedene neue Schlüsselwortargumente wie depends erhalten. Ältere Versionen der Distutils brechen ab, wenn sie unbekannte Schlüsselwörter erhalten. Eine Lösung besteht darin, die Anwesenheit der neuen Funktionget_distutil_options()in Ihrersetup.pyzu überprüfen und die neuen Schlüsselwörter nur mit einer Version der Distutils zu verwenden, die sie unterstützt.from distutils import core kw = {'sources': 'foo.c', ...} if hasattr(core, 'get_distutil_options'): kw['depends'] = ['foo.h'] ext = Extension(**kw)
Die Verwendung von
Noneals Variablennamen führt jetzt zu einerSyntaxWarning.Die Namen von Erweiterungstypen, die von den mit Python gelieferten Modulen definiert werden, enthalten nun das Modul und einen Punkt (
'.') vor dem Typnamen.
Danksagungen¶
Der Autor möchte sich bei folgenden Personen für Vorschläge, Korrekturen und Hilfestellungen bei verschiedenen Entwürfen dieses Artikels bedanken: Jeff Bauer, Simon Brunning, Brett Cannon, Michael Chermside, Andrew Dalke, Scott David Daniels, Fred L. Drake, Jr., David Fraser, Kelly Gerber, Raymond Hettinger, Michael Hudson, Chris Lambert, Detlef Lannert, Martin von Löwis, Andrew MacIntyre, Lalo Martins, Chad Netzer, Gustavo Niemeyer, Neal Norwitz, Hans Nowak, Chris Reedy, Francesco Ricciardi, Vinay Sajip, Neil Schemenauer, Roman Suzi, Jason Tishler, Just van Rossum.