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_hooks ist 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 eine ImportError-Ausnahme aus, wenn es diesen Pfad nicht handhaben kann.

  • sys.path_importer_cache speichert Importer-Objekte für jeden Pfad zwischen, sodass sys.path_hooks nur einmal für jeden Pfad durchlaufen werden muss.

  • sys.meta_path ist eine Liste von Importer-Objekten, die durchlaufen wird, bevor sys.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 yield ist 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, True und False, wurden zusammen mit dem integrierten Typ bool hinzugefügt, wie in Abschnitt PEP 285: A Boolean Type dieses Dokuments beschrieben.

  • Der Typkonstruktor int() gibt nun eine lange Ganzzahl zurück, anstatt eine OverflowError auszulö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, dass isinstance(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 eine KeyError ausgelö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 auf None.

    (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 assert prü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 -O generiert 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 new in einer zukünftigen Python-Version veraltet sein könnte, da Sie nun die Typobjekte verwenden können, die im Modul types verfü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 Sie warnings.filterwarnings().

  • Der Prozess der Veralterung von zeichenkettenbasierten Ausnahmen, wie in raise "Error occurred", hat begonnen. Das Auslösen eines Strings löst nun PendingDeprecationWarning aus.

  • Die Verwendung von None als Variablennamen führt nun zu einer SyntaxWarning-Warnung. In einer zukünftigen Python-Version könnte None schließ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 einfach for line in file_obj schreiben. Dateiobjekte haben auch ein neues schreibgeschütztes Attribut encoding, 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 Funktion sys.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 in verhält sich für Strings nun anders. Zuvor, bei der Auswertung von X 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, und X in Y gibt True zurück, wenn X* ein Substring von *Y* ist. Wenn *X* der leere String ist, ist das Ergebnis immer True.

    >>> '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() und rstrip() 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() und endswith() akzeptieren nun negative Zahlen für die Parameter start und end.

  • Eine weitere neue String-Methode ist zfill(), ursprünglich eine Funktion im string-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 als zfill() 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, sodass isinstance(obj, basestring) für beide Arten von Strings True zurückgibt. Es handelt sich um einen vollständig abstrakten Typ, sodass keine Instanzen von basestring erstellt 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, was for i in xrange(n) etwas schneller macht als for 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 bsddb185 umbenannt und wird nicht mehr automatisch erstellt. Sie müssen Modules/Setup bearbeiten, um es zu aktivieren. Beachten Sie, dass das neue bsddb-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 Skripten db2pickle.py und pickle2db.py erledigen, die Sie im Verzeichnis Tools/scripts der Distribution finden. Wenn Sie bereits das PyBSDDB-Paket verwendet und es als bsddb3 importiert haben, müssen Sie Ihre import-Anweisungen ändern, um es als bsddb zu importieren.

  • Das neue Modul bz2 ist eine Schnittstelle zur bzip2-Datenkomprimierungsbibliothek. bzip2-komprimierte Daten sind normalerweise kleiner als entsprechende zlib-komprimierte Daten. (Beigesteuert von Gustavo Niemeyer.)

  • Eine Reihe von Standard-Datums-/Zeit-Typen wurde im neuen Modul datetime hinzugefü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 beispielsweise sampmodule.c die Header-Datei sample.h einbindet, würden Sie das Extension-Objekt wie folgt erstellen:

    ext = Extension("samp",
                    sources=["sampmodule.c"],
                    depends=["sample.h"])
    

    Das Ändern von sample.h wü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, LDFLAGS und CPPFLAGS überprüft, mit denen die Einstellungen in der Python-Konfiguration überschrieben werden (beigesteuert von Robert Weber).

  • Zuvor durchsuchte das Modul doctest nur die Docstrings von öffentlichen Methoden und Funktionen nach Testfällen, aber nun werden auch private untersucht. Die Funktion DocTestSuite() erstellt ein unittest.TestSuite-Objekt aus einer Reihe von doctest-Tests.

  • Die neue Funktion gc.get_referents(object) gibt eine Liste aller Objekte zurück, auf die von object verwiesen wird.

  • Das Modul getopt erhielt eine neue Funktion, gnu_getopt(), die dieselben Argumente wie die bestehende Funktion getopt() unterstützt, aber den Scanning-Modus im GNU-Stil verwendet. Die bestehende Funktion getopt() 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, pwd und resource geben nun erweiterte Tupel zurück.

    >>> import grp
    >>> g = grp.getgrnam('amk')
    >>> g.gr_name, g.gr_gid
    ('amk', 500)
    
  • Das Modul gzip kann nun Dateien mit mehr als 2 GiB verarbeiten.

  • Das neue Modul heapq enthä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] und heap[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 heapq bietet die Funktionen heappush() und heappop() 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 Paket idlelib in die Standardbibliothek integriert.

  • Das Modul imaplib unterstützt nun IMAP über SSL. (Beigesteuert von Piers Lauder und Tino Lange.)

  • Das Modul itertools enthält eine Reihe nützlicher Funktionen für die Arbeit mit Iteratoren, inspiriert von verschiedenen Funktionen der Sprachen ML und Haskell. Zum Beispiel gibt itertools.ifilter(predicate, iterator) alle Elemente im Iterator zurück, für die die Funktion predicate() True zurückgibt, und itertools.repeat(obj, N) gibt obj N 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) und radians(degs), konvertieren zwischen Radiant und Grad. Andere Funktionen im Modul math wie math.sin() und math.cos() haben immer Eingabewerte in Radiant erfordert. Außerdem wurde ein optionales Argument base zu math.log() hinzugefügt, um die Berechnung von Logarithmen zu Basen außer e und 10 zu erleichtern. (Beigesteuert von Raymond Hettinger.)

  • Mehrere neue POSIX-Funktionen (getpgid(), killpg(), lchown(), loadavg(), major(), makedev(), minor() und mknod()) wurden dem Modul posix hinzugefügt, das dem Modul os zugrunde liegt. (Beigesteuert von Gustavo Niemeyer, Geert Jansen und Denis S. Otkidach.)

  • Im Modul os können die Funktionen der *stat()-Familie nun Bruchteile von Sekunden in einem Zeitstempel melden. Solche Zeitstempel werden als Gleitkommazahlen dargestellt, ähnlich dem Wert, der von time.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_result die 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 optparse enthä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 linuxaudiodev wurde veraltet, und eine neue Version namens ossaudiodev wurde 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 platform enthä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 pyexpat bereitgestellten können nun optional Zeichendaten puffern, was zu weniger Aufrufen Ihrer Zeichendaten-Handler und damit zu einer schnelleren Leistung führt. Das Setzen des Attributs buffer_text des Parser-Objekts auf True aktiviert das Puffern.

  • Die Funktion sample(population, k) wurde dem Modul random hinzugefügt. population ist eine Sequenz oder ein xrange-Objekt, das die Elemente einer Population enthält, und sample() wählt k Elemente aus der Population ohne Ersetzung aus. k kann jeden Wert bis zu len(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 random verwendet 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 readline erhielt ebenfalls eine Reihe neuer Funktionen: get_history_item(), get_current_history_length() und redisplay().

  • Die Module rexec und Bastion wurden als veraltet deklariert, und Versuche, sie zu importieren, führen zu einem RuntimeError. Klassen des neuen Stils bieten neue Möglichkeiten, aus der eingeschränkten Ausführungsumgebung von rexec auszubrechen, und niemand hat Interesse oder Zeit, sie zu reparieren. Wenn Sie Anwendungen haben, die rexec verwenden, 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 rexec vorhanden sind. Um es zu wiederholen: Wenn Sie rexec verwenden, hören Sie sofort damit auf!)

  • Das Modul rotor wurde 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 shutil erhielt eine Funktion move(src, dest), die eine Datei oder ein Verzeichnis rekursiv an einen neuen Ort verschiebt.

  • Unterstützung für erweiterte POSIX-Signalbehandlung wurde zum Modul signal hinzugefügt, dann aber wieder entfernt, da es sich als unmöglich erwies, sie plattformübergreifend zuverlässig zum Laufen zu bringen.

  • Das Modul socket unterstützt nun Timeouts. Sie können die Methode settimeout(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 Ausnahme socket.timeout aus.

    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 socket nun mit Unterstützung für Secure Sockets Layer (SSL) ausgeliefert.

  • Der Wert des C PYTHON_API_VERSION-Makros wird nun auf Python-Ebene als sys.api_version verfügbar gemacht. Die aktuelle Ausnahme kann durch Aufruf der neuen Funktion sys.exc_clear() gelöscht werden.

  • Das neue Modul tarfile ermöglicht das Lesen und Schreiben von Archivdateien im tar-Format. (Beigetragen von Lars Gustäbel.)

  • Das neue Modul textwrap enthält Funktionen zum Umbrechen von Zeichenketten, die Textabsätze enthalten. Die Funktion wrap(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 Funktion fill(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, basiert fill() auf wrap(). 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 Klasse TextWrapper als auch die Funktionen wrap() und fill() 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 thread und threading haben jetzt Begleitmodule, dummy_thread und dummy_threading, die eine Nichtstun-Implementierung der Schnittstelle des thread-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 wird

    try:
        import threading as _threading
    except ImportError:
        import dummy_threading as _threading
    

    In diesem Beispiel wird _threading als Modulname verwendet, um deutlich zu machen, dass das verwendete Modul nicht unbedingt das tatsächliche threading-Modul ist. Der Code kann Funktionen aufrufen und Klassen in _threading verwenden, unabhängig davon, ob Threads unterstützt werden oder nicht, wodurch eine if-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 Moduls time war lange Zeit ein Ärgernis, da sie die Implementierung von strptime() 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 timeit hilft bei der Messung der Ausführungszeit von Python-Code-Snippets. Die Datei timeit.py kann direkt von der Kommandozeile ausgeführt werden, oder die Klasse Timer des 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 Funktion unicode() schneller ist

    import 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 Tix hat verschiedene Fehlerkorrekturen und Aktualisierungen für die aktuelle Version des Tix-Pakets erhalten.

  • Das Modul Tkinter funktioniert 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 vermeidet Tkinter dies 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, aber Tkinter lö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 _tkinter gibt 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 Methode wantobjects() von tkapp-Objekten gesteuert werden.

    Wenn _tkinter über das Modul Tkinter verwendet 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 wantobjects im Modul Tkinter auf false gesetzt wird, bevor das erste tkapp-Objekt erstellt wird.

    import Tkinter
    Tkinter.wantobjects = 0
    

    Jegliche durch diese Änderung verursachten Probleme sollten als Fehler gemeldet werden.

  • Das Modul UserDict hat eine neue Klasse DictMixin, 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 Modul shelve.

    Das Hinzufügen des Mix-ins als Oberklasse bietet die vollständige Dictionary-Schnittstelle, wann immer die Klasse __getitem__(), __setitem__(), __delitem__() und keys() 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.minidom kann nun XML-Ausgaben in einer bestimmten Kodierung generieren, indem ein optionales Kodierungsargument an die Methoden toxml() und toprettyxml() von DOM-Knoten übergeben wird.

  • Das Modul xmlrpclib unterstützt nun eine XML-RPC-Erweiterung für die Handhabung von Nil-Datenwerten wie Pythons None. Nil-Werte werden beim Entpacken einer XML-RPC-Antwort immer unterstützt. Um Anfragen mit None zu generieren, müssen Sie für den Parameter allow_none einen wahren Wert angeben, wenn Sie eine Instanz von Marshaller erstellen.

  • Das neue Modul DocXMLRPCServer ermö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 socket wurde 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. httplib und ftplib) unterstützen ebenfalls Unicode-Hostnamen; httplib sendet auch HTTP Host-Header unter Verwendung der ACE-Version des Domainnamens. urllib unterstützt Unicode-URLs mit Nicht-ASCII-Hostnamen, solange der path-Teil der URL nur ASCII enthält.

    Zur Implementierung dieser Änderung wurden das Modul stringprep, das Werkzeug mkstringprep und die Kodierung punycode hinzugefü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.

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.c im 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-gc für configure wurde entfernt.

  • Python kann nun optional als Shared Library (libpython2.3.so) erstellt werden, indem --enable-shared beim Ausführen des configure-Skripts von Python angegeben wird. (Beigetragen von Ondrej Palkovsky.)

  • Die Makros DL_EXPORT und DL_IMPORT sind nun veraltet. Initialisierungsfunktionen für Python-Erweiterungsmodule sollten nun mit dem neuen Makro PyMODINIT_FUNC deklariert werden, während der Python-Kern im Allgemeinen die Makros PyAPI_FUNC und PyAPI_DATA verwenden wird.

  • Der Interpreter kann ohne Docstrings für die eingebauten Funktionen und Module kompiliert werden, indem --without-doc-strings an 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 Flag METH_NOARGS angeben, 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 stattdessen PyArg_ParseTuple(args, "") verwenden, aber dies ist langsamer als die Verwendung von METH_NOARGS.

  • PyArg_ParseTuple() akzeptiert neue Formatzeichen für verschiedene Größen von vorzeichenlosen Ganzzahlen: B für unsigned char, H für unsigned short int, I für unsigned int und K für unsigned long long.

  • Eine neue Funktion, PyObject_DelItemString(mapping, char *key), wurde als Kurzform für PyObject_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.py erheblich 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_CLASS oder METH_STATIC in der PyMethodDef-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 PYTHONINSPECT gesetzt ist, wird der Python-Interpreter nach der Ausführung eines Python-Programms in die interaktive Eingabeaufforderung wechseln, als ob Python mit der Option -i aufgerufen 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.py bietet 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ßer bsddb zu aktivieren.

  • Die Werkzeuge, die zum Erstellen der Dokumentation verwendet werden, funktionieren jetzt sowohl unter Cygwin als auch unter Unix.

  • Der SET_LINENO Opcode wurde entfernt. Früher war dieser Opcode erforderlich, um Zeilennummern in Tracebacks zu erzeugen und Trace-Funktionen zu unterstützen (z. B. für pdb). 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 von SET_LINENO vollständig entfiel.

    Es wäre schwierig, einen daraus resultierenden Unterschied im Python-Code zu erkennen, abgesehen von einer leichten Beschleunigung, wenn Python ohne -O ausgeführt wird.

    C-Erweiterungen, die auf das Feld f_lineno von Frame-Objekten zugreifen, sollten stattdessen PyCode_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_lineno von Frame-Objekten Werte zuweisen können, wodurch die als nächstes auszuführende Zeile geändert wird. Dem pdb-Debugger wurde ein jump-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.

  • yield ist 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 Y jetzt auch dann, wenn X mehr als ein Zeichen lang ist.

  • Der Typkonstruktor int() gibt jetzt eine lange Ganzzahl zurück, anstatt eine OverflowError auszulö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 _tkinter gibt 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 0xffffffff lösen jetzt eine FutureWarning aus. 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 L am 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 Sie 0xffffffffL &~(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 Funktion get_distutil_options() in Ihrer setup.py zu ü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 None als Variablennamen führt jetzt zu einer SyntaxWarning.

  • 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.