Was ist neu in Python 3.2

Autor:

Raymond Hettinger

Dieser Artikel erklärt die neuen Funktionen in Python 3.2 im Vergleich zu 3.1. Python 3.2 wurde am 20. Februar 2011 veröffentlicht. Er konzentriert sich auf einige Highlights und gibt einige Beispiele. Für vollständige Details siehe die Datei Misc/NEWS.

Siehe auch

PEP 392 - Python 3.2 Release-Zeitplan

PEP 384: Definition einer stabilen ABI

In der Vergangenheit waren Erweiterungsmodule, die für eine Python-Version erstellt wurden, oft nicht mit anderen Python-Versionen verwendbar. Insbesondere unter Windows musste jede Feature-Veröffentlichung von Python alle Erweiterungsmodule neu kompiliert werden, die man verwenden wollte. Diese Anforderung war das Ergebnis des freien Zugangs zu den Interna des Python-Interpreters, die Erweiterungsmodule nutzen konnten.

Mit Python 3.2 wird ein alternativer Ansatz verfügbar: Erweiterungsmodule, die sich auf eine begrenzte API beschränken (durch Definition von Py_LIMITED_API), können viele der Interna nicht nutzen, sind aber auf eine Reihe von API-Funktionen beschränkt, die für mehrere Veröffentlichungen stabil sind. Als Konsequenz werden Erweiterungsmodule, die in diesem Modus für 3.2 erstellt wurden, auch mit 3.3, 3.4 und so weiter funktionieren. Erweiterungsmodule, die Details von Speicherstrukturen nutzen, können weiterhin erstellt werden, müssen aber für jede Feature-Veröffentlichung neu kompiliert werden.

Siehe auch

PEP 384 - Definition einer stabilen ABI

PEP geschrieben von Martin von Löwis.

PEP 389: Argparse Kommandozeilen-Parsing-Modul

Ein neues Modul für das Kommandozeilen-Parsing, argparse, wurde eingeführt, um die Einschränkungen von optparse zu überwinden, das keine Unterstützung für Positionsargumente (nicht nur Optionen), Unterbefehle, erforderliche Optionen und andere gängige Muster zum Spezifizieren und Validieren von Optionen bot.

Dieses Modul hat bereits großen Erfolg als Drittanbieter-Modul in der Community erzielt. Da das argparse-Modul funktionsreicher als sein Vorgänger ist, ist es nun das bevorzugte Modul für die Kommandozeilenverarbeitung. Das ältere Modul wird aufgrund der erheblichen Menge an Legacy-Code, der davon abhängt, weiterhin bereitgestellt.

Hier ist ein kommentiertes Beispiel für einen Parser, der Funktionen wie die Beschränkung von Ergebnissen auf eine Auswahl von Optionen, die Angabe eines Metavar im Hilfebildschirm, die Validierung, dass ein oder mehrere Positionsargumente vorhanden sind, und die Erstellung einer erforderlichen Option zeigt.

import argparse
parser = argparse.ArgumentParser(
            description = 'Manage servers',         # main description for help
            epilog = 'Tested on Solaris and Linux') # displayed after help
parser.add_argument('action',                       # argument name
            choices = ['deploy', 'start', 'stop'],  # three allowed values
            help = 'action on each target')         # help msg
parser.add_argument('targets',
            metavar = 'HOSTNAME',                   # var name used in help msg
            nargs = '+',                            # require one or more targets
            help = 'url for target machines')       # help msg explanation
parser.add_argument('-u', '--user',                 # -u or --user option
            required = True,                        # make it a required argument
            help = 'login as user')

Beispiel für das Aufrufen des Parsers mit einem Kommandozeilenstring

>>> cmd = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'
>>> result = parser.parse_args(cmd.split())
>>> result.action
'deploy'
>>> result.targets
['sneezy.example.com', 'sleepy.example.com']
>>> result.user
'skycaptain'

Beispiel für die automatisch generierte Hilfe des Parsers

>>> parser.parse_args('-h'.split())

usage: manage_cloud.py [-h] -u USER
                       {deploy,start,stop} HOSTNAME [HOSTNAME ...]

Manage servers

positional arguments:
  {deploy,start,stop}   action on each target
  HOSTNAME              url for target machines

optional arguments:
  -h, --help            show this help message and exit
  -u USER, --user USER  login as user

Tested on Solaris and Linux

Eine besonders schöne Funktion von argparse ist die Möglichkeit, Unterparser zu definieren, jeder mit seinen eigenen Argumentmustern und Hilfanzeigen.

import argparse
parser = argparse.ArgumentParser(prog='HELM')
subparsers = parser.add_subparsers()

parser_l = subparsers.add_parser('launch', help='Launch Control')   # first subgroup
parser_l.add_argument('-m', '--missiles', action='store_true')
parser_l.add_argument('-t', '--torpedos', action='store_true')

parser_m = subparsers.add_parser('move', help='Move Vessel',        # second subgroup
                                 aliases=('steer', 'turn'))         # equivalent names
parser_m.add_argument('-c', '--course', type=int, required=True)
parser_m.add_argument('-s', '--speed', type=int, default=0)
$ ./helm.py --help                         # top level help (launch and move)
$ ./helm.py launch --help                  # help for launch options
$ ./helm.py launch --missiles              # set missiles=True and torpedos=False
$ ./helm.py steer --course 180 --speed 5   # set movement parameters

Siehe auch

PEP 389 - Neues Modul für Kommandozeilen-Parsing

PEP geschrieben von Steven Bethard.

Migration von optparse-Code zu argparse für Details zu den Unterschieden zu optparse.

PEP 391: Wörterbuchbasierte Konfiguration für Logging

Das Modul logging bot zwei Arten der Konfiguration: einen Stil mit Funktionsaufrufen für jede Option oder einen anderen Stil, der von einer externen Datei im configparser-Format gesteuert wurde. Diese Optionen boten nicht die Flexibilität, Konfigurationen aus JSON- oder YAML-Dateien zu erstellen, und unterstützten auch keine inkrementelle Konfiguration, die für die Angabe von Logger-Optionen von der Kommandozeile benötigt wird.

Um einen flexibleren Stil zu unterstützen, bietet das Modul nun logging.config.dictConfig() zur Angabe der Logging-Konfiguration mit reinen Python-Wörterbüchern. Die Konfigurationsoptionen umfassen Formatierer, Handler, Filter und Logger. Hier ist ein funktionierendes Beispiel für ein Konfigurationswörterbuch.

{"version": 1,
 "formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},
                "full": {"format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s"}
                },
 "handlers": {"console": {
                   "class": "logging.StreamHandler",
                   "formatter": "brief",
                   "level": "INFO",
                   "stream": "ext://sys.stdout"},
              "console_priority": {
                   "class": "logging.StreamHandler",
                   "formatter": "full",
                   "level": "ERROR",
                   "stream": "ext://sys.stderr"}
              },
 "root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}

Wenn dieses Wörterbuch in einer Datei namens conf.json gespeichert ist, kann es mit Code wie diesem geladen und aufgerufen werden.

>>> import json, logging.config
>>> with open('conf.json') as f:
...     conf = json.load(f)
...
>>> logging.config.dictConfig(conf)
>>> logging.info("Transaction completed normally")
INFO    : root           : Transaction completed normally
>>> logging.critical("Abnormal termination")
2011-02-17 11:14:36,694 root            CRITICAL Abnormal termination

Siehe auch

PEP 391 - Wörterbuchbasierte Konfiguration für Logging

PEP geschrieben von Vinay Sajip.

PEP 3148: Das Modul concurrent.futures

Code zur Erstellung und Verwaltung von Parallelität wird in einem neuen Top-Level-Namespace, concurrent, gesammelt. Sein erstes Mitglied ist ein futures-Paket, das eine einheitliche High-Level-Schnittstelle zur Verwaltung von Threads und Prozessen bietet.

Das Design für concurrent.futures wurde vom Paket java.util.concurrent inspiriert. In diesem Modell werden ein laufender Aufruf und sein Ergebnis durch ein Future-Objekt dargestellt, das Merkmale abstrahiert, die für Threads, Prozesse und Remote-Procedure-Aufrufe gemeinsam sind. Dieses Objekt unterstützt Statusprüfungen (laufend oder abgeschlossen), Timeouts, Abbrüche, Hinzufügen von Rückruffunktionen und Zugriff auf Ergebnisse oder Ausnahmen.

Das Hauptangebot des neuen Moduls sind zwei Executor-Klassen zum Starten und Verwalten von Aufrufen. Ziel der Executors ist es, die Verwendung bestehender Werkzeuge für parallele Aufrufe zu erleichtern. Sie sparen den Aufwand, der für die Einrichtung eines Ressourcenpools, das Starten der Aufrufe, die Erstellung einer Ergebnisschlange, die Hinzufügung von Timeout-Handhabung und die Begrenzung der Gesamtzahl von Threads, Prozessen oder Remote-Procedure-Aufrufen erforderlich ist.

Idealerweise sollte jede Anwendung einen einzigen Executor über mehrere Komponenten hinweg gemeinsam nutzen, damit Prozess- und Thread-Limits zentral verwaltet werden können. Dies löst die Design-Herausforderung, die entsteht, wenn jede Komponente ihre eigene konkurrierende Strategie für das Ressourcenmanagement hat.

Beide Klassen teilen sich eine gemeinsame Schnittstelle mit drei Methoden: submit() zum Planen einer aufrufbaren Funktion und Rückgabe eines Future-Objekts; map() zum gleichzeitigen Planen vieler asynchroner Aufrufe und shutdown() zum Freigeben von Ressourcen. Die Klasse ist ein Kontextmanager und kann in einer with-Anweisung verwendet werden, um sicherzustellen, dass Ressourcen automatisch freigegeben werden, wenn die aktuell ausstehenden Futures fertig ausgeführt sind.

Ein einfaches Beispiel für ThreadPoolExecutor ist der Start von vier parallelen Threads zum Kopieren von Dateien.

import concurrent.futures, shutil
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as e:
    e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
    e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
    e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
    e.submit(shutil.copy, 'src3.txt', 'dest4.txt')

Siehe auch

PEP 3148 - Futures – Berechnungen asynchron ausführen

PEP geschrieben von Brian Quinlan.

Code für parallele Thread-URL-Lesevorgänge, ein Beispiel, das Threads verwendet, um mehrere Webseiten parallel abzurufen.

Code zur parallelen Berechnung von Primzahlen, ein Beispiel, das ProcessPoolExecutor demonstriert.

PEP 3147: PYC Repository-Verzeichnisse

Pythons Schema zum Caching von Bytecode in .pyc-Dateien funktionierte in Umgebungen mit mehreren Python-Interpretern nicht gut. Wenn ein Interpreter auf eine von einem anderen Interpreter erstellte Cache-Datei stieß, kompilierte er die Quelle neu und überschrieb die Cache-Datei, wodurch die Vorteile des Cachings verloren gingen.

Das Problem der "pyc-Kämpfe" wurde ausgeprägter, da es für Linux-Distributionen üblich wurde, mehrere Versionen von Python auszuliefern. Diese Konflikte treten auch bei CPython-Alternativen wie Unladen Swallow auf.

Um dieses Problem zu lösen, wurde Pythons Importmechanismus erweitert, um unterschiedliche Dateinamen für jeden Interpreter zu verwenden. Anstatt dass Python 3.2, Python 3.3 und Unladen Swallow um eine Datei namens "mymodule.pyc" konkurrieren, suchen sie nun nach "mymodule.cpython-32.pyc", "mymodule.cpython-33.pyc" und "mymodule.unladen10.pyc". Und um zu verhindern, dass all diese neuen Dateien Quellverzeichnisse verstopfen, werden die pyc-Dateien nun in einem "__pycache__"-Verzeichnis gesammelt, das unter dem Paketverzeichnis gespeichert ist.

Neben den Dateinamen und Zielverzeichnissen hat das neue Schema einige Aspekte, die für den Programmierer sichtbar sind.

  • Importierte Module haben jetzt ein Attribut __cached__, das den Namen der tatsächlich importierten Datei speichert.

    >>> import collections
    >>> collections.__cached__
    'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
    
  • Das Tag, das für jeden Interpreter eindeutig ist, ist aus Funktionen im Modul imp zugänglich.

    >>> import imp
    >>> imp.get_tag()
    'cpython-32'
    
  • Skripte, die versuchen, den Quellcode-Dateinamen aus der importierten Datei abzuleiten, müssen nun intelligenter sein. Es reicht nicht mehr aus, einfach "c" von einem ".pyc"-Dateinamen zu entfernen. Verwenden Sie stattdessen die neuen Funktionen im Modul imp.

    >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc')
    'c:/py32/lib/collections.py'
    >>> imp.cache_from_source('c:/py32/lib/collections.py')
    'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
    
  • Die Module py_compile und compileall wurden aktualisiert, um die neue Namenskonvention und das Zielverzeichnis widerzuspiegeln. Die Kommandozeilenaufrufe von compileall haben neue Optionen: -i zur Angabe einer Liste von zu kompilierenden Dateien und Verzeichnissen und -b, das bewirkt, dass Bytecode-Dateien am alten Speicherort anstatt in __pycache__ geschrieben werden.

  • Das Modul importlib.abc wurde um neue abstrakte Basisklassen zum Laden von Bytecode-Dateien erweitert. Die veralteten ABCs, PyLoader und PyPycLoader, wurden als veraltet markiert (Anweisungen zur Kompatibilität mit Python 3.1 sind in der Dokumentation enthalten).

Siehe auch

PEP 3147 - PYC Repository-Verzeichnisse

PEP geschrieben von Barry Warsaw.

PEP 3149: ABI-Version-getaggte .so-Dateien

Das PYC-Repository-Verzeichnis ermöglicht es, mehrere Bytecode-Cache-Dateien im selben Verzeichnis zu speichern. Diese PEP implementiert einen ähnlichen Mechanismus für Shared-Object-Dateien, indem ihnen ein gemeinsames Verzeichnis und eindeutige Namen für jede Version gegeben werden.

Das gemeinsame Verzeichnis ist "pyshared" und die Dateinamen werden durch die Identifizierung der Python-Implementierung (z.B. CPython, PyPy, Jython usw.), der Haupt- und Nebenversionsnummern und optionaler Build-Flags (wie "d" für Debug, "m" für pymalloc, "u" für Wide-Unicode) eindeutig gemacht. Für ein beliebiges Paket "foo" könnten Sie diese Dateien sehen, wenn das Distributionspaket installiert ist.

/usr/share/pyshared/foo.cpython-32m.so
/usr/share/pyshared/foo.cpython-33md.so

In Python selbst sind die Tags über Funktionen im Modul sysconfig zugänglich.

>>> import sysconfig
>>> sysconfig.get_config_var('SOABI')       # find the version tag
'cpython-32mu'
>>> sysconfig.get_config_var('EXT_SUFFIX')  # find the full filename extension
'.cpython-32mu.so'

Siehe auch

PEP 3149 - ABI-Version-getaggte .so-Dateien

PEP geschrieben von Barry Warsaw.

PEP 3333: Python Web Server Gateway Interface v1.0.1

Diese informative PEP klärt, wie Byte/Text-Probleme vom WSGI-Protokoll behandelt werden sollen. Die Herausforderung besteht darin, dass die String-Verarbeitung in Python 3 am einfachsten mit dem Typ str gehandhabt wird, obwohl das HTTP-Protokoll selbst byteweise orientiert ist.

Die PEP unterscheidet zwischen sogenannten native strings, die für Request/Response-Header und Metadaten verwendet werden, und byte strings, die für die Bodies von Requests und Responses verwendet werden.

Die native strings sind immer vom Typ str, sind aber auf Codepunkte zwischen U+0000 und U+00FF beschränkt, die mit der Kodierung Latin-1 in Bytes umgewandelt werden können. Diese Strings werden für die Schlüssel und Werte im Umgebungswörterbuch und für Antwort-Header und -Status in der Funktion start_response() verwendet. Sie müssen in Bezug auf die Kodierung RFC 2616 folgen. Das heißt, sie müssen entweder ISO-8859-1-Zeichen sein oder die RFC 2047 MIME-Kodierung verwenden.

Für Entwickler, die WSGI-Anwendungen von Python 2 portieren, sind hier die wichtigsten Punkte:

  • Wenn die App bereits Zeichenketten für Header in Python 2 verwendete, ist keine Änderung erforderlich.

  • Wenn die App stattdessen Ausgabesteuerungen kodierte oder Eingabesteuerungen dekodierte, müssen die Steuerungen in Latin-1 neu kodiert werden. Zum Beispiel muss ein in UTF-8 kodierter Ausgabesteuerkopf, der h.encode('utf-8') verwendete, jetzt von Bytes in native Zeichenketten konvertiert werden, indem h.encode('utf-8').decode('latin-1') verwendet wird.

  • Werte, die von einer Anwendung geliefert oder mit der Methode write() gesendet werden, müssen Byte-Strings sein. Die Funktion start_response() und environ müssen native Zeichenketten verwenden. Die beiden können nicht gemischt werden.

Für Server-Implementierer, die CGI-zu-WSGI-Pfade oder andere CGI-ähnliche Protokolle schreiben, müssen die Benutzer auf die Umgebung mit nativen Zeichenketten zugreifen können, auch wenn die zugrunde liegende Plattform eine andere Konvention hat. Um diese Lücke zu schließen, bietet das Modul wsgiref eine neue Funktion, wsgiref.handlers.read_environ(), zum Transkodieren von CGI-Variablen aus os.environ in native Zeichenketten und zum Zurückgeben eines neuen Wörterbuchs.

Siehe auch

PEP 3333 - Python Web Server Gateway Interface v1.0.1

PEP geschrieben von Phillip Eby.

Andere Sprachänderungen

Einige kleinere Änderungen am Kern der Python-Sprache sind:

  • Die String-Formatierung für format() und str.format() hat neue Möglichkeiten für das Formatierungszeichen **#** erhalten. Zuvor verursachte es bei ganzen Zahlen in Binär-, Oktal- oder Hexadezimalform die Präfixierung der Ausgabe mit '0b', '0o' bzw. '0x'. Jetzt kann es auch Gleitkommazahlen, komplexe Zahlen und Decimal verarbeiten, wodurch die Ausgabe immer einen Dezimalpunkt hat, auch wenn keine Ziffern folgen.

    >>> format(20, '#o')
    '0o24'
    >>> format(12.34, '#5.0f')
    '  12.'
    

    (Vorgeschlagen von Mark Dickinson und implementiert von Eric Smith in bpo-7094.)

  • Es gibt auch eine neue Methode str.format_map(), die die Fähigkeiten der bestehenden Methode str.format() erweitert, indem sie beliebige Mapping-Objekte akzeptiert. Diese neue Methode ermöglicht die Verwendung von String-Formatierung mit jedem von Pythons vielen wörterbuchähnlichen Objekten wie defaultdict, Shelf, ConfigParser oder dbm. Sie ist auch nützlich mit benutzerdefinierten dict-Unterklassen, die Schlüssel vor dem Nachschlagen normalisieren oder eine __missing__()-Methode für unbekannte Schlüssel bereitstellen.

    >>> import shelve
    >>> d = shelve.open('tmp.shl')
    >>> 'The {project_name} status is {status} as of {date}'.format_map(d)
    'The testing project status is green as of February 15, 2011'
    
    >>> class LowerCasedDict(dict):
    ...     def __getitem__(self, key):
    ...         return dict.__getitem__(self, key.lower())
    ...
    >>> lcd = LowerCasedDict(part='widgets', quantity=10)
    >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd)
    'There are 10 widgets in stock'
    
    >>> class PlaceholderDict(dict):
    ...     def __missing__(self, key):
    ...         return '<{}>'.format(key)
    ...
    >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict())
    'Hello <name>, welcome to <location>'
    

(Vorgeschlagen von Raymond Hettinger und implementiert von Eric Smith in bpo-6081.)

  • Der Interpreter kann nun mit der stillen Option -q gestartet werden, um die Anzeige der Copyright- und Versionsinformationen im interaktiven Modus zu verhindern. Die Option kann über das Attribut sys.flags abgefragt werden.

    $ python -q
    >>> sys.flags
    sys.flags(debug=0, division_warning=0, inspect=0, interactive=0,
    optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0,
    ignore_environment=0, verbose=0, bytes_warning=0, quiet=1)
    

    (Beigetragen von Marcin Wojdyr in bpo-1772833).

  • Die Funktion hasattr() arbeitet, indem sie getattr() aufruft und erkennt, ob eine Ausnahme ausgelöst wird. Diese Technik ermöglicht es ihr, Methoden zu erkennen, die dynamisch von __getattr__() oder __getattribute__() erstellt werden und die sonst im Klassenwörterbuch fehlen würden. Zuvor fing hasattr jede Ausnahme ab und maskierte möglicherweise echte Fehler. Nun wurde hasattr verschärft, um nur AttributeError abzufangen und andere Ausnahmen durchzulassen.

    >>> class A:
    ...     @property
    ...     def f(self):
    ...         return 1 // 0
    ...
    >>> a = A()
    >>> hasattr(a, 'f')
    Traceback (most recent call last):
      ...
    ZeroDivisionError: integer division or modulo by zero
    

    (Entdeckt von Yury Selivanov und behoben von Benjamin Peterson; bpo-9666.)

  • Die Ausgabe von str() für eine Gleitkomma- oder komplexe Zahl entspricht nun seiner Ausgabe von repr(). Zuvor war die str()-Form kürzer, aber das verursachte nur Verwirrung und ist nicht mehr notwendig, da die kürzeste mögliche Ausgabe von repr() standardmäßig angezeigt wird.

    >>> import math
    >>> repr(math.pi)
    '3.141592653589793'
    >>> str(math.pi)
    '3.141592653589793'
    

    (Vorgeschlagen und implementiert von Mark Dickinson; bpo-9337.)

  • memoryview-Objekte haben nun eine Methode release() und unterstützen nun auch das Kontextmanagement-Protokoll. Dies ermöglicht die rechtzeitige Freigabe von Ressourcen, die bei der Anforderung eines Puffers vom ursprünglichen Objekt erworben wurden.

    >>> with memoryview(b'abcdefgh') as v:
    ...     print(v.tolist())
    [97, 98, 99, 100, 101, 102, 103, 104]
    

    (Hinzugefügt von Antoine Pitrou; bpo-9757.)

  • Zuvor war es illegal, einen Namen aus dem lokalen Namensraum zu löschen, wenn er als freie Variable in einem verschachtelten Block vorkam.

    def outer(x):
        def inner():
            return x
        inner()
        del x
    

    Dies ist nun erlaubt. Denken Sie daran, dass das Ziel einer except-Klausel gelöscht wird, so dass dieser Code, der mit Python 2.6 funktionierte, mit Python 3.1 eine SyntaxError auslöste und nun wieder funktioniert.

    def f():
        def print_error():
            print(e)
        try:
            something
        except Exception as e:
            print_error()
            # implicit "del e" here
    

    (Siehe bpo-4617.)

  • Struct-Sequenztypen sind nun Unterklassen von Tupeln. Das bedeutet, dass C-Strukturen, wie sie von os.stat(), time.gmtime() und sys.version_info zurückgegeben werden, nun wie ein Named Tuple funktionieren und nun mit Funktionen und Methoden arbeiten, die ein Tupel als Argument erwarten. Dies ist ein großer Schritt zur Flexibilisierung der C-Strukturen, damit sie ihren reinen Python-Gegenstücken gleichkommen.

    >>> import sys
    >>> isinstance(sys.version_info, tuple)
    True
    >>> 'Version %d.%d.%d %s(%d)' % sys.version_info
    'Version 3.2.0 final(0)'
    

    (Vorgeschlagen von Arfrever Frehtes Taifersar Arahesis und implementiert von Benjamin Peterson in bpo-8413.)

  • Warnungen sind nun einfacher zu steuern, indem die Umgebungsvariable PYTHONWARNINGS als Alternative zur Verwendung von -W auf der Kommandozeile verwendet wird.

    $ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'
    

    (Vorgeschlagen von Barry Warsaw und implementiert von Philip Jenvey in bpo-7301.)

  • Eine neue Warnungskategorie, ResourceWarning, wurde hinzugefügt. Sie wird ausgegeben, wenn potenzielle Probleme mit dem Ressourcenverbrauch oder der Bereinigung erkannt werden. Sie wird in normalen Release-Builds standardmäßig unterdrückt, kann aber über die Mittel des Moduls warnings oder auf der Kommandozeile aktiviert werden.

    Eine ResourceWarning wird beim Herunterfahren des Interpreters ausgegeben, wenn die Liste gc.garbage nicht leer ist, und wenn gc.DEBUG_UNCOLLECTABLE gesetzt ist, werden alle nicht sammelbaren Objekte gedruckt. Dies soll den Programmierer darauf aufmerksam machen, dass sein Code Probleme mit der Objektfinalisierung enthält.

    Eine ResourceWarning wird auch ausgegeben, wenn ein Dateiobjekt zerstört wird, ohne explizit geschlossen worden zu sein. Obwohl der Deallocator eines solchen Objekts sicherstellt, dass die zugrunde liegende Betriebssystemressource (normalerweise ein Dateideskriptor) geschlossen wird, konnte die Verzögerung bei der Deallokation des Objekts verschiedene Probleme verursachen, insbesondere unter Windows. Hier ist ein Beispiel, wie die Warnung von der Kommandozeile aktiviert wird.

    $ python -q -Wdefault
    >>> f = open("foo", "wb")
    >>> del f
    __main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>
    

    (Hinzugefügt von Antoine Pitrou und Georg Brandl in bpo-10093 und bpo-477863.)

  • range-Objekte unterstützen nun die Methoden index und count. Dies ist Teil einer Anstrengung, mehr Objekte vollständig die collections.Sequence abstrakte Basisklasse implementieren zu lassen. Infolgedessen wird die Sprache eine einheitlichere API haben. Darüber hinaus unterstützen range-Objekte nun Slicing und negative Indizes, auch mit Werten, die größer als sys.maxsize sind. Dies macht range interoperabler mit Listen.

    >>> range(0, 100, 2).count(10)
    1
    >>> range(0, 100, 2).index(10)
    5
    >>> range(0, 100, 2)[5]
    10
    >>> range(0, 100, 2)[0:5]
    range(0, 10, 2)
    

    (Beigetragen von Daniel Stutzbach in bpo-9213, von Alexander Belopolsky in bpo-2690 und von Nick Coghlan in bpo-10889.)

  • Die eingebaute Funktion callable() aus Py2.x wurde wiederbelebt. Sie bietet eine prägnante, lesbare Alternative zur Verwendung einer abstrakten Basisklasse in einem Ausdruck wie isinstance(x, collections.Callable).

    >>> callable(max)
    True
    >>> callable(20)
    False
    

    (Siehe bpo-10518.)

  • Pythons Import-Mechanismus kann nun Module laden, die in Verzeichnissen mit nicht-ASCII-Zeichen im Pfadnamen installiert sind. Dies löste ein ärgerliches Problem mit Home-Verzeichnissen für Benutzer mit Nicht-ASCII-Zeichen in ihren Benutzernamen.

(Umfangreiche Arbeit von Victor Stinner in bpo-9425 erforderlich.)

Neue, verbesserte und veraltete Module

Pythons Standardbibliothek hat umfangreiche Wartungsarbeiten und Qualitätsverbesserungen erfahren.

Die größte Nachricht für Python 3.2 ist, dass das Paket email, das Modul mailbox und das Modul nntplib nun korrekt mit dem Bytes/Text-Modell in Python 3 funktionieren. Zum ersten Mal gibt es eine korrekte Behandlung von Nachrichten mit gemischten Kodierungen.

In der gesamten Standardbibliothek wurde mehr Sorgfalt auf Kodierungen und Text- versus Byte-Probleme gelegt. Insbesondere Interaktionen mit dem Betriebssystem können nun besser nicht-ASCII-Daten über die Windows-MBCS-Kodierung, lokalisierungsabhängige Kodierungen oder UTF-8 austauschen.

Ein weiterer bedeutender Erfolg ist die Hinzufügung einer erheblich verbesserten Unterstützung für SSL-Verbindungen und Sicherheitszertifikate.

Darüber hinaus implementieren nun mehr Klassen einen Kontextmanager, um eine bequeme und zuverlässige Ressourcenbereinigung mit einer with-Anweisung zu unterstützen.

email

Die Benutzerfreundlichkeit des Pakets email in Python 3 wurde durch die umfangreichen Bemühungen von R. David Murray größtenteils behoben. Das Problem bestand darin, dass E-Mails typischerweise in Form von Bytes und nicht als str-Text gelesen und gespeichert werden und sie mehrere Kodierungen innerhalb einer einzigen E-Mail enthalten können. Daher musste das E-Mail-Paket erweitert werden, um E-Mail-Nachrichten im Byte-Format zu parsen und zu generieren.

  • Neue Funktionen message_from_bytes() und message_from_binary_file() sowie neue Klassen BytesFeedParser und BytesParser ermöglichen das Parsen von binären Nachrichten in Modellobjekte.

  • Wenn der Modellierung Bytes-Eingaben übergeben werden, dekodiert get_payload() standardmäßig den Nachrichtenkörper, der eine Content-Transfer-Encoding von 8bit aufweist, mit der in den MIME-Headern angegebenen Zeichenkodierung und gibt den resultierenden String zurück.

  • Wenn der Modellierung Bytes-Eingaben übergeben werden, konvertiert Generator Nachrichtenkörper mit einer Content-Transfer-Encoding von 8bit so, dass sie stattdessen eine 7bit Content-Transfer-Encoding aufweisen.

    Header mit unkodierten Nicht-ASCII-Bytes werden als RFC 2047-kodiert mit der Zeichenkodierung unknown-8bit betrachtet.

  • Eine neue Klasse BytesGenerator erzeugt Bytes als Ausgabe und bewahrt alle unveränderten Nicht-ASCII-Daten, die in der zur Erstellung des Modells verwendeten Eingabe vorhanden waren, einschließlich Nachrichtenkörper mit einer Content-Transfer-Encoding von 8bit.

  • Die Klasse smtplib SMTP akzeptiert nun eine Byte-Zeichenkette für das Argument msg der Methode sendmail(), und eine neue Methode send_message() akzeptiert ein Message-Objekt und kann optional die Adressen from_addr und to_addrs direkt aus dem Objekt beziehen.

(Vorgeschlagen und implementiert von R. David Murray, bpo-4661 und bpo-10321.)

elementtree

Das Paket xml.etree.ElementTree und sein Gegenstück xml.etree.cElementTree wurden auf Version 1.3 aktualisiert.

Mehrere neue und nützliche Funktionen und Methoden wurden hinzugefügt

Zwei Methoden wurden als veraltet markiert

  • xml.etree.ElementTree.getchildren() verwenden Sie stattdessen list(elem).

  • xml.etree.ElementTree.getiterator() verwenden Sie stattdessen Element.iter.

Details zum Update finden Sie unter Introducing ElementTree auf der Website von Fredrik Lundh.

(Beigetragen von Florent Xicluna und Fredrik Lundh, bpo-6472.)

functools

  • Das Modul functools enthält einen neuen Dekorator zum Cachen von Funktionsaufrufen. functools.lru_cache() kann wiederholte Abfragen an eine externe Ressource speichern, wenn die Ergebnisse voraussichtlich gleich sind.

    Das Hinzufügen eines Caching-Dekorators zu einer Datenbankabfragefunktion kann beispielsweise Datenbankzugriffe für beliebte Suchen einsparen.

    >>> import functools
    >>> @functools.lru_cache(maxsize=300)
    ... def get_phone_number(name):
    ...     c = conn.cursor()
    ...     c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))
    ...     return c.fetchone()[0]
    
    >>> for name in user_requests:
    ...     get_phone_number(name)        # cached lookup
    

    Um die Auswahl einer effektiven Cache-Größe zu unterstützen, wird die gewrappte Funktion zur Nachverfolgung von Cache-Statistiken instrumentiert.

    >>> get_phone_number.cache_info()
    CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)
    

    Wenn die Telefonliste aktualisiert wird, kann der veraltete Inhalt des Caches gelöscht werden mit

    >>> get_phone_number.cache_clear()
    

    (Beigetragen von Raymond Hettinger und unter Einbeziehung von Designideen von Jim Baker, Miki Tebeka und Nick Coghlan; siehe Rezept 498245, Rezept 577479, bpo-10586 und bpo-10593.)

  • Der Dekorator functools.wraps() fügt nun ein Attribut __wrapped__ hinzu, das auf die ursprüngliche aufrufbare Funktion verweist. Dies ermöglicht die Inspektion von gewrappten Funktionen. Er kopiert auch __annotations__, falls definiert. Und nun überspringt er auch elegant fehlende Attribute wie __doc__, die für die gewrappte aufrufbare Funktion möglicherweise nicht definiert sind.

    Im obigen Beispiel kann der Cache gelöscht werden, indem die ursprüngliche Funktion wiederhergestellt wird

    >>> get_phone_number = get_phone_number.__wrapped__    # uncached function
    

    (Von Nick Coghlan und Terrence Cole; bpo-9567, bpo-3445 und bpo-8814.)

  • Um die Erstellung von Klassen mit Rich-Comparison-Methoden zu erleichtern, verwendet ein neuer Dekorator functools.total_ordering() bestehende Gleichheits- und Ungleichheitsmethoden, um die verbleibenden Methoden zu füllen.

    Beispielsweise wird durch die Bereitstellung von \_\_eq\_\_ und \_\_lt\_\_ total_ordering() ermöglicht, \_\_le\_\_, \_\_gt\_\_ und \_\_ge\_\_ zu füllen.

    @total_ordering
    class Student:
        def __eq__(self, other):
            return ((self.lastname.lower(), self.firstname.lower()) ==
                    (other.lastname.lower(), other.firstname.lower()))
    
        def __lt__(self, other):
            return ((self.lastname.lower(), self.firstname.lower()) <
                    (other.lastname.lower(), other.firstname.lower()))
    

    Mit dem total_ordering-Dekorator werden die verbleibenden Vergleichsmethoden automatisch ausgefüllt.

    (Beigetragen von Raymond Hettinger.)

  • Zur Unterstützung der Portierung von Programmen aus Python 2 konvertiert die Funktion functools.cmp_to_key() eine alte Vergleichsfunktion in eine moderne Schlüsselfunktion

    >>> # locale-aware sort order
    >>> sorted(iterable, key=cmp_to_key(locale.strcoll))
    

    Beispiele zum Sortieren und eine kurze Sortieranleitung finden Sie im Sortier-HowTo.

    (Beigetragen von Raymond Hettinger.)

itertools

  • Das Modul itertools verfügt über eine neue Funktion accumulate(), die nach dem Scan-Operator von APL und der accumulate-Funktion von Numpy modelliert ist.

    >>> from itertools import accumulate
    >>> list(accumulate([8, 2, 50]))
    [8, 10, 60]
    
    >>> prob_dist = [0.1, 0.4, 0.2, 0.3]
    >>> list(accumulate(prob_dist))      # cumulative probability distribution
    [0.1, 0.5, 0.7, 1.0]
    

    Ein Beispiel für die Verwendung von accumulate() finden Sie in den Beispielen für das random-Modul.

    (Beigetragen von Raymond Hettinger und unter Einbeziehung von Designvorschlägen von Mark Dickinson.)

collections

  • Die Klasse collections.Counter verfügt nun über zwei Formen der In-Place-Subtraktion: den bestehenden Operator -= für saturierende Subtraktion und die neue Methode subtract() für die normale Subtraktion. Die erstere eignet sich für Multisets, die nur positive Zählungen aufweisen, und die letztere eignet sich besser für Anwendungsfälle, die negative Zählungen zulassen.

    >>> from collections import Counter
    >>> tally = Counter(dogs=5, cats=3)
    >>> tally -= Counter(dogs=2, cats=8)    # saturating subtraction
    >>> tally
    Counter({'dogs': 3})
    
    >>> tally = Counter(dogs=5, cats=3)
    >>> tally.subtract(dogs=2, cats=8)      # regular subtraction
    >>> tally
    Counter({'dogs': 3, 'cats': -5})
    

    (Beigetragen von Raymond Hettinger.)

  • Die Klasse collections.OrderedDict hat eine neue Methode move_to_end(), die einen vorhandenen Schlüssel nimmt und ihn entweder an die erste oder die letzte Position in der geordneten Sequenz verschiebt.

    Standardmäßig wird ein Element an die letzte Position verschoben. Dies entspricht der Erneuerung eines Eintrags mit od[k] = od.pop(k).

    Eine schnelle Verschiebeoperation an das Ende ist nützlich für die Neuordnung von Einträgen. Beispielsweise kann ein geordnetes Dictionary verwendet werden, um die Zugriffsreihenfolge zu verfolgen, indem Einträge vom ältesten zum zuletzt zugegriffenen „altern“ gelassen werden.

    >>> from collections import OrderedDict
    >>> d = OrderedDict.fromkeys(['a', 'b', 'X', 'd', 'e'])
    >>> list(d)
    ['a', 'b', 'X', 'd', 'e']
    >>> d.move_to_end('X')
    >>> list(d)
    ['a', 'b', 'd', 'e', 'X']
    

    (Beigetragen von Raymond Hettinger.)

  • Die Klasse collections.deque hat zwei neue Methoden erhalten: count() und reverse(), die sie besser zu einem Ersatz für list-Objekte machen.

    >>> from collections import deque
    >>> d = deque('simsalabim')
    >>> d.count('s')
    2
    >>> d.reverse()
    >>> d
    deque(['m', 'i', 'b', 'a', 'l', 'a', 's', 'm', 'i', 's'])
    

    (Beigetragen von Raymond Hettinger.)

threading

Das Modul threading verfügt über eine neue Synchronisationsklasse Barrier, die mehrere Threads warten lässt, bis alle einen gemeinsamen Schwellenpunkt erreicht haben. Barrieren sind nützlich, um sicherzustellen, dass eine Aufgabe mit mehreren Vorbedingungen nicht ausgeführt wird, bevor alle vorgelagerten Aufgaben abgeschlossen sind.

Barrieren können mit einer beliebigen Anzahl von Threads arbeiten. Dies ist eine Verallgemeinerung eines Rendezvous, das für nur zwei Threads definiert ist.

Implementiert als zweiphasige zyklische Barriere, sind Barrier-Objekte für die Verwendung in Schleifen geeignet. Die separaten Phasen filling und draining stellen sicher, dass alle Threads freigegeben (drained) werden, bevor einer von ihnen zurückschleifen und die Barriere erneut betreten kann. Die Barriere wird nach jedem Zyklus vollständig zurückgesetzt.

Beispiel für die Verwendung von Barrieren

from threading import Barrier, Thread

def get_votes(site):
    ballots = conduct_election(site)
    all_polls_closed.wait()        # do not count until all polls are closed
    totals = summarize(ballots)
    publish(site, totals)

all_polls_closed = Barrier(len(sites))
for site in sites:
    Thread(target=get_votes, args=(site,)).start()

In diesem Beispiel erzwingt die Barriere die Regel, dass Stimmen an keinem Wahllokal gezählt werden dürfen, bevor alle Wahllokale geschlossen sind. Beachten Sie, dass eine Lösung mit einer Barriere einer mit threading.Thread.join() ähnelt, aber die Threads am Leben bleiben und nach Überquerung des Schwellenpunkts weiterarbeiten (Abstimmungszettel zusammenfassen).

Wenn eine der vorgelagerten Aufgaben hängen bleibt oder sich verzögert, kann eine Barriere mit einem optionalen timeout-Parameter erstellt werden. Wenn dann das Timeout-Intervall abläuft, bevor alle vorgelagerten Aufgaben den Schwellenpunkt erreichen, werden alle wartenden Threads freigegeben und eine BrokenBarrierError-Ausnahme ausgelöst.

def get_votes(site):
    ballots = conduct_election(site)
    try:
        all_polls_closed.wait(timeout=midnight - time.now())
    except BrokenBarrierError:
        lockbox = seal_ballots(ballots)
        queue.put(lockbox)
    else:
        totals = summarize(ballots)
        publish(site, totals)

In diesem Beispiel erzwingt die Barriere eine robustere Regel. Wenn einige Wahllokale nicht vor Mitternacht fertig werden, schlägt die Barriere mit einem Timeout fehl, und die Stimmzettel werden versiegelt und in einer Warteschlange zur späteren Bearbeitung abgelegt.

Siehe Barrier Synchronization Patterns für weitere Beispiele, wie Barrieren im parallelen Rechnen verwendet werden können. Außerdem gibt es eine einfache, aber gründliche Erklärung von Barrieren in The Little Book of Semaphores, Abschnitt 3.6.

(Beigetragen von Kristján Valur Jónsson mit einer API-Überprüfung durch Jeffrey Yasskin in bpo-8777.)

Datum und Uhrzeit

  • Das Modul datetime hat einen neuen Typ timezone, der die Schnittstelle tzinfo implementiert, indem er einen festen UTC-Offset und einen Zeitzonennamen zurückgibt. Dies erleichtert die Erstellung zeitzonenbewusster Datetime-Objekte.

    >>> from datetime import datetime, timezone
    
    >>> datetime.now(timezone.utc)
    datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc)
    
    >>> datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z")
    datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)
    
  • Auch timedelta-Objekte können nun mit float multipliziert und durch float und int-Objekte dividiert werden. Und timedelta-Objekte können nun miteinander dividiert werden.

  • Die Methode datetime.date.strftime() ist nicht mehr auf Jahre nach 1900 beschränkt. Der neue unterstützte Jahresbereich ist von 1000 bis 9999 einschließlich.

  • Wenn in einem Zeit-Tupel ein zweistelliges Jahr verwendet wird, wurde die Interpretation durch time.accept2dyear gesteuert. Der Standardwert ist True, was bedeutet, dass für ein zweistelliges Jahr das Jahrhundert gemäß den POSIX-Regeln für das Format %y strptime erraten wird.

    Ab Py3.2 wird die Verwendung der Heuristik zum Erraten des Jahrhunderts eine DeprecationWarning auslösen. Stattdessen wird empfohlen, time.accept2dyear auf False zu setzen, damit große Datumsbereiche ohne Raten verwendet werden können.

    >>> import time, warnings
    >>> warnings.resetwarnings()      # remove the default warning filters
    
    >>> time.accept2dyear = True      # guess whether 11 means 11 or 2011
    >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))
    Warning (from warnings module):
      ...
    DeprecationWarning: Century info guessed for a 2-digit year.
    'Fri Jan  1 12:34:56 2011'
    
    >>> time.accept2dyear = False     # use the full range of allowable dates
    >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))
    'Fri Jan  1 12:34:56 11'
    

    Mehrere Funktionen haben nun deutlich erweiterte Datumsbereiche. Wenn time.accept2dyear falsch ist, akzeptiert die Funktion time.asctime() jedes Jahr, das in einen C-int passt, während die Funktionen time.mktime() und time.strftime() den vollständigen Bereich akzeptieren, der von den entsprechenden Betriebssystemfunktionen unterstützt wird.

(Beigetragen von Alexander Belopolsky und Victor Stinner in bpo-1289118, bpo-5094, bpo-6641, bpo-2706, bpo-1777412, bpo-8013 und bpo-10827.)

math

Das Modul math wurde um sechs neue Funktionen erweitert, die vom C99-Standard inspiriert sind.

Die Funktion isfinite() bietet eine zuverlässige und schnelle Möglichkeit, spezielle Werte zu erkennen. Sie gibt True für reguläre Zahlen und False für Nan oder Infinity zurück.

>>> from math import isfinite
>>> [isfinite(x) for x in (123, 4.56, float('Nan'), float('Inf'))]
[True, True, False, False]

Die Funktion expm1() berechnet e**x-1 für kleine Werte von x, ohne den Genauigkeitsverlust zu erleiden, der normalerweise mit der Subtraktion von fast gleichen Mengen einhergeht.

>>> from math import expm1
>>> expm1(0.013671875)   # more accurate way to compute e**x-1 for a small x
0.013765762467652909

Die Funktion erf() berechnet ein Wahrscheinlichkeitsintegral oder eine Gaußsche Fehlerfunktion. Die komplementäre Fehlerfunktion, erfc(), ist 1 - erf(x).

>>> from math import erf, erfc, sqrt
>>> erf(1.0/sqrt(2.0))   # portion of normal distribution within 1 standard deviation
0.682689492137086
>>> erfc(1.0/sqrt(2.0))  # portion of normal distribution outside 1 standard deviation
0.31731050786291404
>>> erf(1.0/sqrt(2.0)) + erfc(1.0/sqrt(2.0))
1.0

Die Funktion gamma() ist eine kontinuierliche Erweiterung der Fakultätsfunktion. Details finden Sie unter https://en.wikipedia.org/wiki/Gamma_function. Da die Funktion mit Fakultäten zusammenhängt, wächst sie auch für kleine Werte von x stark an, daher gibt es auch eine Funktion lgamma() zur Berechnung des natürlichen Logarithmus der Gammafunktion.

>>> from math import gamma, lgamma
>>> gamma(7.0)           # six factorial
720.0
>>> lgamma(801.0)        # log(800 factorial)
4551.950730698041

(Beigetragen von Mark Dickinson.)

abc

Das Modul abc unterstützt nun abstractclassmethod() und abstractstaticmethod().

Diese Werkzeuge ermöglichen die Definition einer abstrakten Basisklasse, die eine bestimmte classmethod() oder staticmethod() implementieren muss.

class Temperature(metaclass=abc.ABCMeta):
    @abc.abstractclassmethod
    def from_fahrenheit(cls, t):
        ...
    @abc.abstractclassmethod
    def from_celsius(cls, t):
        ...

(Patch eingereicht von Daniel Urban; bpo-5867.)

io

Die Klasse io.BytesIO hat eine neue Methode getbuffer(), die eine Funktionalität ähnlich zu memoryview() bietet. Sie erstellt eine bearbeitbare Ansicht der Daten, ohne eine Kopie zu erstellen. Der zufällige Zugriff des Puffers und die Unterstützung für Slice-Notation eignen sich gut für die In-Place-Bearbeitung.

>>> REC_LEN, LOC_START, LOC_LEN = 34, 7, 11

>>> def change_location(buffer, record_number, location):
...     start = record_number * REC_LEN + LOC_START
...     buffer[start: start+LOC_LEN] = location

>>> import io

>>> byte_stream = io.BytesIO(
...     b'G3805  storeroom  Main chassis    '
...     b'X7899  shipping   Reserve cog     '
...     b'L6988  receiving  Primary sprocket'
... )
>>> buffer = byte_stream.getbuffer()
>>> change_location(buffer, 1, b'warehouse  ')
>>> change_location(buffer, 0, b'showroom   ')
>>> print(byte_stream.getvalue())
b'G3805  showroom   Main chassis    '
b'X7899  warehouse  Reserve cog     '
b'L6988  receiving  Primary sprocket'

(Beigetragen von Antoine Pitrou in bpo-5506.)

reprlib

Beim Schreiben einer Methode __repr__() für einen benutzerdefinierten Container vergisst man leicht, den Fall zu behandeln, dass ein Mitglied auf den Container selbst zurückverweist. Pythons eingebaute Objekte wie list und set behandeln Selbstbezüge, indem sie „…“ im rekursiven Teil des Darstellung-Strings anzeigen.

Um solche Methoden __repr__() zu schreiben, verfügt das Modul reprlib über einen neuen Dekorator recursive_repr(), um rekursive Aufrufe von __repr__() zu erkennen und stattdessen eine Platzhalterzeichenkette zu ersetzen.

>>> class MyList(list):
...     @recursive_repr()
...     def __repr__(self):
...         return '<' + '|'.join(map(repr, self)) + '>'
...
>>> m = MyList('abc')
>>> m.append(m)
>>> m.append('x')
>>> print(m)
<'a'|'b'|'c'|...|'x'>

(Beigetragen von Raymond Hettinger in bpo-9826 und bpo-9840.)

logging

Zusätzlich zur oben beschriebenen dictionary-basierten Konfiguration weist das Paket logging viele weitere Verbesserungen auf.

Die Dokumentation zur Protokollierung wurde durch ein Grundlagen-Tutorial, ein fortgeschrittenes Tutorial und ein Kochbuch mit Protokollierungsrezepten ergänzt. Diese Dokumente sind der schnellste Weg, um mehr über die Protokollierung zu erfahren.

Die Setup-Funktion logging.basicConfig() hat ein Argument style erhalten, um drei verschiedene Arten der String-Formatierung zu unterstützen. Standardmäßig ist es "%" für die traditionelle %-Formatierung, es kann auf "{" für den neuen Stil der str.format()-Methode gesetzt werden oder es kann auf "$" für die Shell-Formatierung gesetzt werden, die von string.Template bereitgestellt wird. Die folgenden drei Konfigurationen sind äquivalent.

>>> from logging import basicConfig
>>> basicConfig(style='%', format="%(name)s -> %(levelname)s: %(message)s")
>>> basicConfig(style='{', format="{name} -> {levelname} {message}")
>>> basicConfig(style='$', format="$name -> $levelname: $message")

Wenn vor dem Eintreten eines Protokollierungsereignisses keine Konfiguration festgelegt ist, gibt es nun eine Standardkonfiguration mit einem StreamHandler, der auf sys.stderr für Ereignisse der Stufe WARNING oder höher gerichtet ist. Zuvor würde ein Ereignis, das vor der Einrichtung einer Konfiguration auftritt, entweder eine Ausnahme auslösen oder das Ereignis stillschweigend verwerfen, abhängig vom Wert von logging.raiseExceptions. Der neue Standardhandler wird in logging.lastResort gespeichert.

Die Verwendung von Filtern wurde vereinfacht. Anstatt ein Objekt Filter zu erstellen, kann das Prädikat jede Python-aufrufbare Funktion sein, die True oder False zurückgibt.

Es gab eine Reihe weiterer Verbesserungen, die Flexibilität hinzufügen und die Konfiguration vereinfachen. Die Moduldokumentation enthält eine vollständige Liste der Änderungen in Python 3.2.

csv

Das Modul csv unterstützt nun einen neuen Dialekt, unix_dialect, der für alle Felder Anführungszeichen und einen traditionellen Unix-Stil mit '\n' als Zeilenabschluss verwendet. Der registrierte Dialektname ist unix.

Die Klasse csv.DictWriter hat eine neue Methode, writeheader(), zum Schreiben einer anfänglichen Zeile, um die Feldnamen zu dokumentieren.

>>> import csv, sys
>>> w = csv.DictWriter(sys.stdout, ['name', 'dept'], dialect='unix')
>>> w.writeheader()
"name","dept"
>>> w.writerows([
...     {'name': 'tom', 'dept': 'accounting'},
...     {'name': 'susan', 'dept': 'Salesl'}])
"tom","accounting"
"susan","sales"

(Neuer Dialekt vorgeschlagen von Jay Talbot in bpo-5975, und die neue Methode vorgeschlagen von Ed Abraham in bpo-1537721.)

contextlib

Es gibt ein neues und etwas verblüffendes Werkzeug ContextDecorator, das hilfreich ist, um einen Kontextmanager zu erstellen, der sowohl als Funktions-Decorator dient.

Zur Bequemlichkeit wird diese neue Funktionalität von contextmanager() verwendet, sodass kein zusätzlicher Aufwand erforderlich ist, um beide Rollen zu unterstützen.

Die Grundidee ist, dass sowohl Kontextmanager als auch Funktions-Decorator für Vor- und Nachaktionen verwendet werden können. Kontextmanager umschließen eine Gruppe von Anweisungen mit einer with-Anweisung, und Funktions-Decorator umschließen eine Gruppe von Anweisungen, die in einer Funktion enthalten sind. Daher besteht gelegentlich die Notwendigkeit, eine Vor- oder Nachaktions-Hülle zu schreiben, die in beiden Rollen verwendet werden kann.

Zum Beispiel ist es manchmal nützlich, Funktionen oder Gruppen von Anweisungen mit einem Logger zu umschließen, der die Zeit des Eintritts und Austritts verfolgen kann. Anstatt für diese Aufgabe sowohl einen Funktions-Decorator als auch einen Kontextmanager zu schreiben, bietet contextmanager() beide Fähigkeiten in einer einzigen Definition.

from contextlib import contextmanager
import logging

logging.basicConfig(level=logging.INFO)

@contextmanager
def track_entry_and_exit(name):
    logging.info('Entering: %s', name)
    yield
    logging.info('Exiting: %s', name)

Zuvor war dies nur als Kontextmanager nutzbar.

with track_entry_and_exit('widget loader'):
    print('Some time consuming activity goes here')
    load_widget()

Jetzt kann es auch als Decorator verwendet werden.

@track_entry_and_exit('widget loader')
def activity():
    print('Some time consuming activity goes here')
    load_widget()

Der Versuch, zwei Rollen gleichzeitig zu erfüllen, schränkt die Technik etwas ein. Kontextmanager haben normalerweise die Flexibilität, ein Argument zurückzugeben, das von einer with-Anweisung verwendet werden kann, aber für Funktions-Decorator gibt es keine Entsprechung.

Im obigen Beispiel gibt es keine saubere Möglichkeit, wie der Kontextmanager track_entry_and_exit eine Logging-Instanz für die Verwendung im Rumpf der umschlossenen Anweisungen zurückgeben kann.

(Beigetragen von Michael Foord in bpo-9110.)

decimal und fractions

Mark Dickinson hat ein elegantes und effizientes Schema zur Sicherstellung entwickelt, dass verschiedene numerische Datentypen den gleichen Hash-Wert haben, wenn ihre tatsächlichen Werte gleich sind (bpo-8188).

assert hash(Fraction(3, 2)) == hash(1.5) == \
       hash(Decimal("1.5")) == hash(complex(1.5, 0))

Einige der Hashing-Details sind über ein neues Attribut, sys.hash_info, zugänglich, das die Bitbreite des Hash-Werts, den Primzahlmodulus, die Hash-Werte für infinity und nan sowie den Multiplikator für den Imaginärteil einer Zahl beschreibt.

>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)

Eine frühe Entscheidung, die Interoperabilität verschiedener numerischer Typen einzuschränken, wurde gelockert. Das implizite Mischen in arithmetischen Ausdrücken wie Decimal('1.1') + float('1.1') ist weiterhin nicht unterstützt (und nicht ratsam), da letzteres beim Erstellen des binären Floats Informationen verliert. Da jedoch bestehende Fließkommawerte verlustfrei in eine Dezimal- oder rationale Darstellung konvertiert werden können, ist es sinnvoll, sie dem Konstruktor hinzuzufügen und Vergleiche von gemischten Typen zu unterstützen.

  • Der Konstruktor decimal.Decimal akzeptiert nun direkt float-Objekte, sodass die Methode from_float() nicht mehr benötigt wird (bpo-8257).

  • Vergleiche von gemischten Typen werden nun vollständig unterstützt, so dass Decimal-Objekte direkt mit float und fractions.Fraction verglichen werden können (bpo-2531 und bpo-8188).

Ähnliche Änderungen wurden an fractions.Fraction vorgenommen, sodass die Methoden from_float() und from_decimal() nicht mehr benötigt werden (bpo-8294).

>>> from decimal import Decimal
>>> from fractions import Fraction
>>> Decimal(1.1)
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)

Eine weitere nützliche Änderung für das Modul decimal ist, dass das Attribut Context.clamp nun öffentlich ist. Dies ist nützlich, um Kontexte zu erstellen, die den Dezimal-Austauschformaten gemäß IEEE 754 entsprechen (siehe bpo-8540).

(Beigetragen von Mark Dickinson und Raymond Hettinger.)

ftp

Die Klasse ftplib.FTP unterstützt nun das Kontextmanagementprotokoll, um socket.error-Ausnahmen bedingungslos zu verwerfen und die FTP-Verbindung zu schließen, wenn sie nicht mehr benötigt wird.

>>> from ftplib import FTP
>>> with FTP("ftp1.at.proftpd.org") as ftp:
        ftp.login()
        ftp.dir()

'230 Anonymous login ok, restrictions apply.'
dr-xr-xr-x   9 ftp      ftp           154 May  6 10:43 .
dr-xr-xr-x   9 ftp      ftp           154 May  6 10:43 ..
dr-xr-xr-x   5 ftp      ftp          4096 May  6 10:43 CentOS
dr-xr-xr-x   3 ftp      ftp            18 Jul 10  2008 Fedora

Andere dateiähnliche Objekte wie mmap.mmap und fileinput.input() erhielten ebenfalls automatisch schließende Kontextmanager.

with fileinput.input(files=('log1.txt', 'log2.txt')) as f:
    for line in f:
        process(line)

(Beigetragen von Tarek Ziadé und Giampaolo Rodolà in bpo-4972, und von Georg Brandl in bpo-8046 und bpo-1286.)

Die Klasse FTP_TLS akzeptiert nun einen context-Parameter, der ein ssl.SSLContext-Objekt ist, welches das Bündeln von SSL-Konfigurationsoptionen, Zertifikaten und privaten Schlüsseln in einer einzelnen (möglicherweise langlebigen) Struktur ermöglicht.

(Beigetragen von Giampaolo Rodolà; bpo-8806.)

popen

Die Funktionen os.popen() und subprocess.Popen() unterstützen nun with-Anweisungen zur automatischen Schließung der File-Deskriptoren.

(Beigetragen von Antoine Pitrou und Brian Curtin in bpo-7461 und bpo-10554.)

select

Das Modul select stellt nun ein neues, konstantes Attribut, PIPE_BUF, zur Verfügung, das die minimale Anzahl von Bytes angibt, die garantiert nicht blockieren, wenn select.select() meldet, dass eine Pipe zum Schreiben bereit ist.

>>> import select
>>> select.PIPE_BUF
512

(Verfügbar unter Unix-Systemen. Patch von Sébastien Sablé in bpo-9862)

gzip und zipfile

gzip.GzipFile implementiert nun die io.BufferedIOBase abstrakte Basisklasse (außer truncate()). Sie verfügt außerdem über eine Methode peek() und unterstützt nicht-seekbare sowie Null-aufgefüllte Dateiobjekte.

Das Modul gzip erhält auch die Funktionen gzip.compress() und gzip.decompress() für eine einfachere Komprimierung und Dekomprimierung im Speicher. Beachten Sie, dass Text vor dem Komprimieren und Dekomprimieren als bytes kodiert werden muss.

>>> import gzip
>>> s = 'Three shall be the number thou shalt count, '
>>> s += 'and the number of the counting shall be three'
>>> b = s.encode()                        # convert to utf-8
>>> len(b)
89
>>> c = gzip.compress(b)
>>> len(c)
77
>>> gzip.decompress(c).decode()[:42]      # decompress and convert to text
'Three shall be the number thou shalt count'

(Beigetragen von Anand B. Pillai in bpo-3488; und von Antoine Pitrou, Nir Aides und Brian Curtin in bpo-9962, bpo-1675951, bpo-7471 und bpo-2846.)

Außerdem wurde die Klasse zipfile.ZipExtFile intern überarbeitet, um Dateien innerhalb eines Archivs darzustellen. Die neue Implementierung ist deutlich schneller und kann für weitere Geschwindigkeitssteigerungen in ein io.BufferedReader-Objekt eingepackt werden. Sie löst auch ein Problem, bei dem verschachtelte Aufrufe von read und readline falsche Ergebnisse lieferten.

(Patch eingereicht von Nir Aides in bpo-7610.)

tarfile

Die Klasse tarfile.TarFile kann nun als Kontextmanager verwendet werden. Darüber hinaus verfügt ihre Methode add() über eine neue Option, filter, die steuert, welche Dateien dem Archiv hinzugefügt werden, und die Bearbeitung der Dateimetadaten ermöglicht.

Die neue Option filter ersetzt den älteren, weniger flexiblen Parameter exclude, der nun als veraltet gilt. Wenn angegeben, muss der optionale Parameter filter ein Keyword-Argument sein. Die vom Benutzer bereitgestellte Filterfunktion akzeptiert ein TarInfo-Objekt und gibt ein aktualisiertes TarInfo-Objekt zurück. Wenn die Datei ausgeschlossen werden soll, kann die Funktion None zurückgeben.

>>> import tarfile, glob

>>> def myfilter(tarinfo):
...     if tarinfo.isfile():             # only save real files
...         tarinfo.uname = 'monty'      # redact the user name
...         return tarinfo

>>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:
...     for filename in glob.glob('*.txt'):
...         tf.add(filename, filter=myfilter)
...     tf.list()
-rw-r--r-- monty/501        902 2011-01-26 17:59:11 annotations.txt
-rw-r--r-- monty/501        123 2011-01-26 17:59:11 general_questions.txt
-rw-r--r-- monty/501       3514 2011-01-26 17:59:11 prion.txt
-rw-r--r-- monty/501        124 2011-01-26 17:59:11 py_todo.txt
-rw-r--r-- monty/501       1399 2011-01-26 17:59:11 semaphore_notes.txt

(Vorgeschlagen von Tarek Ziadé und implementiert von Lars Gustäbel in bpo-6856.)

hashlib

Das Modul hashlib enthält zwei neue Konstantenattribute, die die Hash-Algorithmen auflisten, die garantiert in allen Implementierungen vorhanden sind, und diejenigen, die in der aktuellen Implementierung verfügbar sind.

>>> import hashlib

>>> hashlib.algorithms_guaranteed
{'sha1', 'sha224', 'sha384', 'sha256', 'sha512', 'md5'}

>>> hashlib.algorithms_available
{'md2', 'SHA256', 'SHA512', 'dsaWithSHA', 'mdc2', 'SHA224', 'MD4', 'sha256',
'sha512', 'ripemd160', 'SHA1', 'MDC2', 'SHA', 'SHA384', 'MD2',
'ecdsa-with-SHA1','md4', 'md5', 'sha1', 'DSA-SHA', 'sha224',
'dsaEncryption', 'DSA', 'RIPEMD160', 'sha', 'MD5', 'sha384'}

(Vorgeschlagen von Carl Chenet in bpo-7418.)

ast

Das Modul ast bietet ein wunderbares, allgemeines Werkzeug zur sicheren Auswertung von Ausdrücken in Zeichenketten unter Verwendung der Python-Literal-Syntax. Die Funktion ast.literal_eval() dient als sichere Alternative zur integrierten Funktion eval(), die leicht missbraucht werden kann. Python 3.2 fügt bytes und set-Literale zur Liste der unterstützten Typen hinzu: Strings, Bytes, Zahlen, Tupel, Listen, Dictionaries, Sets, Booleans und None.

>>> from ast import literal_eval

>>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"
>>> literal_eval(request)
{'args': (2, 0.5), 'req': 3, 'func': 'pow'}

>>> request = "os.system('do something harmful')"
>>> literal_eval(request)
Traceback (most recent call last):
  ...
ValueError: malformed node or string: <_ast.Call object at 0x101739a10>

(Implementiert von Benjamin Peterson und Georg Brandl.)

os

Verschiedene Betriebssysteme verwenden unterschiedliche Kodierungen für Dateinamen und Umgebungsvariablen. Das Modul os stellt zwei neue Funktionen, os.fsencode() und os.fsdecode(), zum Kodieren und Dekodieren von Dateinamen zur Verfügung.

>>> import os
>>> filename = 'Sehenswürdigkeiten'
>>> os.fsencode(filename)
b'Sehensw\xc3\xbcrdigkeiten'

Einige Betriebssysteme erlauben den direkten Zugriff auf kodierte Bytes in der Umgebung. Wenn dies der Fall ist, ist die Konstante os.supports_bytes_environ wahr.

Für den direkten Zugriff auf kodierte Umgebungsvariablen (falls verfügbar) verwenden Sie die neue Funktion os.getenvb() oder os.environb, welche eine Bytes-Version von os.environ ist.

(Beigetragen von Victor Stinner.)

shutil

Die Funktion shutil.copytree() hat zwei neue Optionen.

  • ignore_dangling_symlinks: wenn symlinks=False ist, kopiert die Funktion die Datei, auf die ein Symlink verweist, nicht den Symlink selbst. Diese Option unterdrückt den Fehler, der ausgelöst wird, wenn die Datei nicht existiert.

  • copy_function: ist ein aufrufbares Objekt, das zum Kopieren von Dateien verwendet wird. Standardmäßig wird shutil.copy2() verwendet.

(Beigetragen von Tarek Ziadé.)

Darüber hinaus unterstützt das Modul shutil nun Archivierungsoperationen für Zip-Dateien, unkomprimierte Tar-Dateien, komprimierte Tar-Dateien und Bzip2-komprimierte Tar-Dateien. Und es gibt Funktionen zur Registrierung weiterer Archivformate (wie XZ-komprimierte Tar-Dateien oder benutzerdefinierte Formate).

Die Hauptfunktionen sind make_archive() und unpack_archive(). Standardmäßig operieren beide im aktuellen Verzeichnis (das mit os.chdir() gesetzt werden kann) und in allen Unterverzeichnissen. Der Archivdateiname muss mit einem vollständigen Pfad angegeben werden. Der Archivierungsschritt ist nicht-destruktiv (die Originaldateien bleiben unverändert).

>>> import shutil, pprint

>>> os.chdir('mydata')  # change to the source directory
>>> f = shutil.make_archive('/var/backup/mydata',
...                         'zip')      # archive the current directory
>>> f                                   # show the name of archive
'/var/backup/mydata.zip'
>>> os.chdir('tmp')                     # change to an unpacking
>>> shutil.unpack_archive('/var/backup/mydata.zip')  # recover the data

>>> pprint.pprint(shutil.get_archive_formats())  # display known formats
[('bztar', "bzip2'ed tar-file"),
 ('gztar', "gzip'ed tar-file"),
 ('tar', 'uncompressed tar file'),
 ('zip', 'ZIP file')]

>>> shutil.register_archive_format(     # register a new archive format
...     name='xz',
...     function=xz.compress,           # callable archiving function
...     extra_args=[('level', 8)],      # arguments to the function
...     description='xz compression'
... )

(Beigetragen von Tarek Ziadé.)

sqlite3

Das Modul sqlite3 wurde auf die Version 2.6.0 von pysqlite aktualisiert. Es verfügt über zwei neue Funktionen.

  • Das Attribut sqlite3.Connection.in_transit ist wahr, wenn eine aktive Transaktion für unbestätigte Änderungen vorliegt.

  • Die Methoden sqlite3.Connection.enable_load_extension() und sqlite3.Connection.load_extension() ermöglichen das Laden von SQLite-Erweiterungen aus „.so“-Dateien. Eine bekannte Erweiterung ist die Fulltext-Search-Erweiterung, die mit SQLite vertrieben wird.

(Beigetragen von R. David Murray und Shashwat Anand; bpo-8845.)

html

Ein neues Modul html wurde eingeführt, das nur eine einzige Funktion enthält, html.escape(), die zum Ersetzen von reservierten Zeichen in HTML-Markup verwendet wird.

>>> import html
>>> html.escape('x > 2 && x < 7')
'x &gt; 2 &amp;&amp; x &lt; 7'

socket

Das Modul socket hat zwei neue Verbesserungen.

  • Socket-Objekte haben nun eine Methode detach(), die den Socket in einen geschlossenen Zustand versetzt, ohne den zugrunde liegenden File-Deskriptor tatsächlich zu schließen. Letzterer kann dann für andere Zwecke wiederverwendet werden. (Hinzugefügt von Antoine Pitrou; bpo-8524.)

  • socket.create_connection() unterstützt nun das Kontextmanagementprotokoll, um socket.error-Ausnahmen bedingungslos zu verwerfen und den Socket zu schließen, wenn er nicht mehr benötigt wird. (Beigetragen von Giampaolo Rodolà; bpo-9794.)

ssl

Das Modul ssl hat eine Reihe von Funktionen hinzugefügt, um gängige Anforderungen für sichere (verschlüsselte, authentifizierte) Internetverbindungen zu erfüllen.

  • Eine neue Klasse, SSLContext, dient als Container für persistente SSL-Daten wie Protokolleinstellungen, Zertifikate, private Schlüssel und verschiedene andere Optionen. Sie enthält eine Methode wrap_socket() zur Erstellung eines SSL-Sockets aus einem SSL-Kontext.

  • Eine neue Funktion, ssl.match_hostname(), unterstützt die Serveridentitätsprüfung für Protokolle höherer Ebene, indem sie die Regeln von HTTPS (aus RFC 2818) implementiert, die auch für andere Protokolle geeignet sind.

  • Der Konstruktor der Funktion ssl.wrap_socket() nimmt nun ein ciphers-Argument entgegen. Die Zeichenkette ciphers listet die erlaubten Verschlüsselungsalgorithmen im Format auf, das in der OpenSSL-Dokumentation beschrieben ist.

  • Wenn gegen aktuelle Versionen von OpenSSL gelinkt wird, unterstützt das Modul ssl nun die Server Name Indication-Erweiterung des TLS-Protokolls, die mehrere „virtuelle Hosts“ mit unterschiedlichen Zertifikaten auf einem einzigen IP-Port ermöglicht. Diese Erweiterung wird nur im Client-Modus unterstützt und wird durch Übergabe des Arguments server_hostname an ssl.SSLContext.wrap_socket() aktiviert.

  • Dem Modul ssl wurden verschiedene Optionen hinzugefügt, wie z.B. ssl.OP_NO_SSLv2, das das unsichere und veraltete SSLv2-Protokoll deaktiviert.

  • Die Erweiterung lädt nun alle OpenSSL-Cipher und Digest-Algorithmen. Wenn einige SSL-Zertifikate nicht verifiziert werden können, werden sie als Fehler „unbekannter Algorithmus“ gemeldet.

  • Die verwendete OpenSSL-Version ist nun über die Modulattribute ssl.OPENSSL_VERSION (eine Zeichenkette), ssl.OPENSSL_VERSION_INFO (ein 5-Tupel) und ssl.OPENSSL_VERSION_NUMBER (eine Ganzzahl) zugänglich.

(Beigetragen von Antoine Pitrou in bpo-8850, bpo-1589, bpo-8322, bpo-5639, bpo-4870, bpo-8484 und bpo-8321.)

nntp

Das Modul nntplib hat eine überarbeitete Implementierung mit besseren Bytes- und Textsemantiken sowie praxisnäheren APIs. Diese Verbesserungen brechen die Kompatibilität mit der nntplib-Version in Python 3.1, die selbst teilweise fehlerhaft war.

Unterstützung für sichere Verbindungen sowohl über implizites (mit nntplib.NNTP_SSL) als auch über explizites (mit nntplib.NNTP.starttls()) TLS wurde ebenfalls hinzugefügt.

(Beigetragen von Antoine Pitrou in bpo-9360 und Andrew Vant in bpo-1926.)

certificates

http.client.HTTPSConnection, urllib.request.HTTPSHandler und urllib.request.urlopen() nehmen nun optionale Argumente für die Überprüfung von Serverzertifikaten gegen eine Menge von Zertifizierungsstellen entgegen, wie es für die öffentliche Nutzung von HTTPS empfohlen wird.

(Hinzugefügt von Antoine Pitrou, bpo-9003.)

imaplib

Unterstützung für explizites TLS bei Standard-IMAP4-Verbindungen wurde durch die neue Methode imaplib.IMAP4.starttls hinzugefügt.

(Beigetragen von Lorenzo M. Catucci und Antoine Pitrou, bpo-4471.)

http.client

Es gab eine Reihe kleiner API-Verbesserungen im http.client Modul. Alte einfache HTTP 0.9-Antworten werden nicht mehr unterstützt und der Parameter strict ist in allen Klassen veraltet.

Die Klassen HTTPConnection und HTTPSConnection verfügen nun über einen Parameter source_address für ein (host, port) Tupel, das angibt, von wo die HTTP-Verbindung hergestellt wird.

Unterstützung für die Zertifikatsprüfung und HTTPS-virtuelle Hosts wurde zu HTTPSConnection hinzugefügt.

Die Methode request() für Verbindungsobjekte erlaubte ein optionales Argument body, so dass ein Datei-Objekt verwendet werden konnte, um den Inhalt der Anfrage bereitzustellen. Praktischerweise akzeptiert das Argument body nun auch ein iterierbares Objekt, solange es einen expliziten Content-Length Header enthält. Diese erweiterte Schnittstelle ist viel flexibler als zuvor.

Um eine HTTPS-Verbindung über einen Proxy-Server herzustellen, gibt es eine neue Methode set_tunnel(), die den Host und Port für das HTTP Connect Tunneling festlegt.

Um das Verhalten von http.server nachzuahmen, kodiert die HTTP-Client-Bibliothek nun auch Header mit der ISO-8859-1 (Latin-1) Kodierung. Sie tat dies bereits für eingehende Header, sodass das Verhalten nun für eingehenden und ausgehenden Datenverkehr konsistent ist. (Siehe Arbeit von Armin Ronacher in bpo-10980.)

unittest

Das unittest-Modul hat eine Reihe von Verbesserungen zur Unterstützung der Test-Erkennung für Pakete, zur einfacheren Experimentation an der interaktiven Eingabeaufforderung, neue Testfallmethoden, verbesserte Diagnosemeldungen für Testfehler und bessere Methodennamen.

  • Der Kommandozeilenaufruf python -m unittest kann nun Dateipfade anstelle von Modulnamen zum Ausführen spezifischer Tests akzeptieren (bpo-10620). Die neue Test-Erkennung kann Tests innerhalb von Paketen finden und alles importierbare aus dem obersten Verzeichnis lokalisieren. Das oberste Verzeichnis kann mit der Option -t, ein Muster zum Abgleichen von Dateien mit -p und ein Verzeichnis zum Starten der Erkennung mit -s angegeben werden.

    $ python -m unittest discover -s my_proj_dir -p _test.py
    

    (Beigetragen von Michael Foord.)

  • Die Experimentation an der interaktiven Eingabeaufforderung ist jetzt einfacher, da die Klasse unittest.TestCase nun ohne Argumente instanziiert werden kann.

    >>> from unittest import TestCase
    >>> TestCase().assertEqual(pow(2, 3), 8)
    

    (Beigetragen von Michael Foord.)

  • Das Modul unittest hat zwei neue Methoden, assertWarns() und assertWarnsRegex(), um zu überprüfen, ob ein bestimmter Warnungstyp durch den zu testenden Code ausgelöst wird.

    with self.assertWarns(DeprecationWarning):
        legacy_function('XYZ')
    

    (Hinzugefügt von Antoine Pitrou, bpo-9754.)

    Eine weitere neue Methode, assertCountEqual(), wird verwendet, um zwei iterierbare Objekte zu vergleichen und festzustellen, ob ihre Elementanzahlen gleich sind (ob die gleichen Elemente mit der gleichen Anzahl von Vorkommen vorhanden sind, unabhängig von der Reihenfolge).

    def test_anagram(self):
        self.assertCountEqual('algorithm', 'logarithm')
    

    (Beigetragen von Raymond Hettinger.)

  • Ein Hauptmerkmal des unittest-Moduls ist die Bemühung, aussagekräftige Diagnosen zu erstellen, wenn ein Test fehlschlägt. Wenn möglich, wird der Fehler zusammen mit einer Differenz des Ausgabestroms aufgezeichnet. Dies ist besonders hilfreich für die Analyse von Log-Dateien fehlgeschlagener Testläufe. Da Differenzen jedoch manchmal umfangreich sein können, gibt es ein neues Attribut maxDiff, das die maximale Länge der angezeigten Differenzen festlegt.

  • Darüber hinaus wurden die Methodennamen im Modul einer Reihe von Bereinigungen unterzogen.

    Zum Beispiel ist assertRegex() der neue Name für assertRegexpMatches(), das falsch benannt war, da der Test re.search() verwendet und nicht re.match(). Andere Methoden, die reguläre Ausdrücke verwenden, werden nun mit der Kurzform "Regex" anstelle von "Regexp" benannt – dies entspricht den Namen, die in anderen unittest-Implementierungen verwendet werden, entspricht dem alten Namen von Python für das Modul re und hat eine eindeutige Camel-Case-Schreibung.

    (Beigetragen von Raymond Hettinger und implementiert von Ezio Melotti.)

  • Zur Verbesserung der Konsistenz werden einige seit langem bestehende Aliasse für Methoden zugunsten der bevorzugten Namen als veraltet markiert.

    Alter Name

    Bevorzugter Name

    assert_()

    assertTrue()

    assertEquals()

    assertEqual()

    assertNotEquals()

    assertNotEqual()

    assertAlmostEquals()

    assertAlmostEqual()

    assertNotAlmostEquals()

    assertNotAlmostEqual()

    Ebenso werden die in Python 3.1 veralteten Methoden TestCase.fail* voraussichtlich in Python 3.3 entfernt.

    (Beigetragen von Ezio Melotti; bpo-9424.)

  • Die Methode assertDictContainsSubset() wurde als veraltet markiert, da sie mit den Argumenten in der falschen Reihenfolge falsch implementiert war. Dies führte zu schwer zu debuggenden optischen Täuschungen, bei denen Tests wie TestCase().assertDictContainsSubset({'a':1, 'b':2}, {'a':1}) fehlschlugen.

    (Beigetragen von Raymond Hettinger.)

random

Die Integer-Methoden im Modul random erzeugen nun gleichmäßigere Verteilungen. Zuvor wurden Auswahlen mit int(n*random()) berechnet, was eine leichte Verzerrung aufwies, wenn n keine Zweierpotenz war. Nun werden mehrere Auswahlen aus einem Bereich bis zur nächsten Zweierpotenz getroffen und eine Auswahl wird nur behalten, wenn sie im Bereich 0 <= x < n liegt. Die betroffenen Funktionen und Methoden sind randrange(), randint(), choice(), shuffle() und sample().

(Beigetragen von Raymond Hettinger; bpo-9025.)

poplib

Die Klasse POP3_SSL akzeptiert nun einen Parameter context, der ein ssl.SSLContext-Objekt ist und die Bündelung von SSL-Konfigurationsoptionen, Zertifikaten und privaten Schlüsseln in einer einzigen (potenziell langlebigen) Struktur ermöglicht.

(Beigetragen von Giampaolo Rodolà; bpo-8807.)

asyncore

asyncore.dispatcher stellt nun eine Methode handle_accepted() bereit, die ein (sock, addr)-Paar zurückgibt und aufgerufen wird, wenn tatsächlich eine Verbindung zu einem neuen entfernten Endpunkt hergestellt wurde. Dies soll als Ersatz für die alte Methode handle_accept() dienen und vermeidet, dass der Benutzer accept() direkt aufrufen muss.

(Beigetragen von Giampaolo Rodolà; bpo-6706.)

tempfile

Das Modul tempfile hat einen neuen Kontextmanager, TemporaryDirectory, der eine einfache deterministische Bereinigung von temporären Verzeichnissen ermöglicht.

with tempfile.TemporaryDirectory() as tmpdirname:
    print('created temporary dir:', tmpdirname)

(Beigetragen von Neil Schemenauer und Nick Coghlan; bpo-5178.)

inspect

  • Das Modul inspect hat eine neue Funktion getgeneratorstate(), um den aktuellen Zustand eines Generator-Iterators einfach zu identifizieren.

    >>> from inspect import getgeneratorstate
    >>> def gen():
    ...     yield 'demo'
    ...
    >>> g = gen()
    >>> getgeneratorstate(g)
    'GEN_CREATED'
    >>> next(g)
    'demo'
    >>> getgeneratorstate(g)
    'GEN_SUSPENDED'
    >>> next(g, None)
    >>> getgeneratorstate(g)
    'GEN_CLOSED'
    

    (Beigetragen von Rodolpho Eckhardt und Nick Coghlan, bpo-10220.)

  • Um Lookups ohne die Möglichkeit, ein dynamisches Attribut zu aktivieren, zu unterstützen, verfügt das Modul inspect über eine neue Funktion, getattr_static(). Im Gegensatz zu hasattr() ist dies eine echte schreibgeschützte Suche, die garantiert keinen Zustand ändert, während sie sucht.

    >>> class A:
    ...     @property
    ...     def f(self):
    ...         print('Running')
    ...         return 10
    ...
    >>> a = A()
    >>> getattr(a, 'f')
    Running
    10
    >>> inspect.getattr_static(a, 'f')
    <property object at 0x1022bd788>
    

(Beigetragen von Michael Foord.)

pydoc

Das Modul pydoc bietet nun eine stark verbesserte Webschnittstelle sowie eine neue Kommandozeilenoption -b, um automatisch ein Browserfenster zu öffnen, das diesen Server anzeigt.

$ pydoc3.2 -b

(Beigetragen von Ron Adam; bpo-2001.)

dis

Das Modul dis erhielt zwei neue Funktionen zur Inspektion von Code, code_info() und show_code(). Beide liefern detaillierte Informationen über das Code-Objekt für die angegebene Funktion, Methode, Quellcode-Zeichenkette oder Code-Objekt. Die erstere gibt eine Zeichenkette zurück, die letztere gibt sie aus.

>>> import dis, random
>>> dis.show_code(random.choice)
Name:              choice
Filename:          /Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/random.py
Argument count:    2
Kw-only arguments: 0
Number of locals:  3
Stack size:        11
Flags:             OPTIMIZED, NEWLOCALS, NOFREE
Constants:
   0: 'Choose a random element from a non-empty sequence.'
   1: 'Cannot choose from an empty sequence'
Names:
   0: _randbelow
   1: len
   2: ValueError
   3: IndexError
Variable names:
   0: self
   1: seq
   2: i

Darüber hinaus akzeptiert die Funktion dis() nun Zeichenkettenargumente, sodass das gängige Idiom dis(compile(s, '', 'eval')) zu dis(s) gekürzt werden kann.

>>> dis('3*x+1 if x%2==1 else x//2')
  1           0 LOAD_NAME                0 (x)
              3 LOAD_CONST               0 (2)
              6 BINARY_MODULO
              7 LOAD_CONST               1 (1)
             10 COMPARE_OP               2 (==)
             13 POP_JUMP_IF_FALSE       28
             16 LOAD_CONST               2 (3)
             19 LOAD_NAME                0 (x)
             22 BINARY_MULTIPLY
             23 LOAD_CONST               1 (1)
             26 BINARY_ADD
             27 RETURN_VALUE
        >>   28 LOAD_NAME                0 (x)
             31 LOAD_CONST               0 (2)
             34 BINARY_FLOOR_DIVIDE
             35 RETURN_VALUE

Zusammengenommen erleichtern diese Verbesserungen die Erkundung der Implementierung von CPython und zeigen Ihnen selbst, was die Sprachsyntax unter der Haube bewirkt.

(Beigetragen von Nick Coghlan in bpo-9147.)

dbm

Alle Datenbankmodule unterstützen nun die Methoden get() und setdefault().

(Vorgeschlagen von Ray Allen in bpo-9523.)

ctypes

Ein neuer Typ, ctypes.c_ssize_t, repräsentiert den C-Datentyp ssize_t.

site

Das Modul site hat drei neue Funktionen, die für die Berichterstattung über die Details einer bestimmten Python-Installation nützlich sind.

  • getsitepackages() listet alle globalen site-packages-Verzeichnisse auf.

  • getuserbase() berichtet über das Basisverzeichnis des Benutzers, in dem Daten gespeichert werden können.

  • getusersitepackages() gibt den Pfad zum benutzerspezifischen site-packages-Verzeichnis an.

>>> import site
>>> site.getsitepackages()
['/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages',
 '/Library/Frameworks/Python.framework/Versions/3.2/lib/site-python',
 '/Library/Python/3.2/site-packages']
>>> site.getuserbase()
'/Users/raymondhettinger/Library/Python/3.2'
>>> site.getusersitepackages()
'/Users/raymondhettinger/Library/Python/3.2/lib/python/site-packages'

Praktischerweise ist ein Teil der Funktionalität von site direkt von der Kommandozeile aus zugänglich.

$ python -m site --user-base
/Users/raymondhettinger/.local
$ python -m site --user-site
/Users/raymondhettinger/.local/lib/python3.2/site-packages

(Beigetragen von Tarek Ziadé in bpo-6693.)

sysconfig

Das neue Modul sysconfig ermöglicht die einfache Ermittlung von Installationspfaden und Konfigurationsvariablen, die auf verschiedenen Plattformen und Installationen variieren.

Das Modul bietet einfachen Zugriff auf Funktionen für Plattform- und Versionsinformationen.

Es bietet auch Zugriff auf die Pfade und Variablen, die zu einem von sieben benannten Schemas gehören, die von distutils verwendet werden. Dazu gehören posix_prefix, posix_home, posix_user, nt, nt_user, os2, os2_home.

  • get_paths() erstellt ein Wörterbuch mit Installationspfaden für das aktuelle Installationsschema.

  • get_config_vars() gibt ein Wörterbuch plattformspezifischer Variablen zurück.

Es gibt auch eine praktische Kommandozeilenschnittstelle.

C:\Python32>python -m sysconfig
Platform: "win32"
Python version: "3.2"
Current installation scheme: "nt"

Paths:
        data = "C:\Python32"
        include = "C:\Python32\Include"
        platinclude = "C:\Python32\Include"
        platlib = "C:\Python32\Lib\site-packages"
        platstdlib = "C:\Python32\Lib"
        purelib = "C:\Python32\Lib\site-packages"
        scripts = "C:\Python32\Scripts"
        stdlib = "C:\Python32\Lib"

Variables:
        BINDIR = "C:\Python32"
        BINLIBDEST = "C:\Python32\Lib"
        EXE = ".exe"
        INCLUDEPY = "C:\Python32\Include"
        LIBDEST = "C:\Python32\Lib"
        SO = ".pyd"
        VERSION = "32"
        abiflags = ""
        base = "C:\Python32"
        exec_prefix = "C:\Python32"
        platbase = "C:\Python32"
        prefix = "C:\Python32"
        projectbase = "C:\Python32"
        py_version = "3.2"
        py_version_nodot = "32"
        py_version_short = "3.2"
        srcdir = "C:\Python32"
        userbase = "C:\Documents and Settings\Raymond\Application Data\Python"

(Aus Distutils verschoben von Tarek Ziadé.)

pdb

Das Debugger-Modul pdb hat eine Reihe von Verbesserungen für die Benutzerfreundlichkeit erhalten.

  • pdb.py hat nun eine Option -c, die Befehle wie in einem Skriptfile .pdbrc ausführt.

  • Ein Skriptfile .pdbrc kann continue und next Befehle enthalten, die das Debugging fortsetzen.

  • Der Konstruktor der Klasse Pdb akzeptiert nun ein Argument nosigint.

  • Neue Befehle: l(list), ll(long list) und source zum Auflisten von Quellcode.

  • Neue Befehle: display und undisplay zum Anzeigen oder Verstecken des Werts eines Ausdrucks, wenn er sich geändert hat.

  • Neuer Befehl: interact zum Starten eines interaktiven Interpreters, der die globalen und lokalen Namen im aktuellen Gültigkeitsbereich enthält.

  • Breakpoints können nach Breakpoint-Nummer gelöscht werden.

(Beigetragen von Georg Brandl, Antonio Cuni und Ilya Sandler.)

configparser

Das Modul configparser wurde modifiziert, um die Benutzerfreundlichkeit und Vorhersehbarkeit des Standard-Parsers und seiner unterstützten INI-Syntax zu verbessern. Die alte Klasse ConfigParser wurde zugunsten von SafeConfigParser entfernt, die ihrerseits in ConfigParser umbenannt wurde. Die Unterstützung für Inline-Kommentare ist nun standardmäßig deaktiviert, und doppelte Abschnitte oder Optionen sind in einer einzelnen Konfigurationsquelle nicht erlaubt.

Config-Parser erhielten eine neue API, die auf dem Mapping-Protokoll basiert.

>>> parser = ConfigParser()
>>> parser.read_string("""
... [DEFAULT]
... location = upper left
... visible = yes
... editable = no
... color = blue
...
... [main]
... title = Main Menu
... color = green
...
... [options]
... title = Options
... """)
>>> parser['main']['color']
'green'
>>> parser['main']['editable']
'no'
>>> section = parser['options']
>>> section['title']
'Options'
>>> section['title'] = 'Options (editable: %(editable)s)'
>>> section['title']
'Options (editable: no)'

Die neue API ist auf der klassischen API implementiert, sodass benutzerdefinierte Parser-Unterklassen sie ohne Modifikationen verwenden können sollten.

Die von den Config-Parsern akzeptierte INI-Datei-Struktur kann nun angepasst werden. Benutzer können alternative Options-/Wert-Trennzeichen und Kommentarpräfixe angeben, den Namen des DEFAULT-Abschnitts ändern oder die Interpolationssyntax wechseln.

Es gibt Unterstützung für steckbare Interpolation, einschließlich eines zusätzlichen Interpolationshandlers ExtendedInterpolation.

>>> parser = ConfigParser(interpolation=ExtendedInterpolation())
>>> parser.read_dict({'buildout': {'directory': '/home/ambv/zope9'},
...                   'custom': {'prefix': '/usr/local'}})
>>> parser.read_string("""
... [buildout]
... parts =
...   zope9
...   instance
... find-links =
...   ${buildout:directory}/downloads/dist
...
... [zope9]
... recipe = plone.recipe.zope9install
... location = /opt/zope
...
... [instance]
... recipe = plone.recipe.zope9instance
... zope9-location = ${zope9:location}
... zope-conf = ${custom:prefix}/etc/zope.conf
... """)
>>> parser['buildout']['find-links']
'\n/home/ambv/zope9/downloads/dist'
>>> parser['instance']['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance = parser['instance']
>>> instance['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance['zope9-location']
'/opt/zope'

Eine Reihe kleinerer Features wurden ebenfalls eingeführt, wie z. B. die Unterstützung für die Angabe der Kodierung bei Lesevorgängen, die Angabe von Fallback-Werten für Get-Funktionen oder das direkte Lesen aus Wörterbüchern und Zeichenketten.

(Alle Änderungen wurden von Łukasz Langa beigetragen.)

urllib.parse

Eine Reihe von Verbesserungen für die Benutzerfreundlichkeit wurden für das Modul urllib.parse vorgenommen.

Die Funktion urlparse() unterstützt nun IPv6-Adressen, wie in RFC 2732 beschrieben.

>>> import urllib.parse
>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
ParseResult(scheme='http',
            netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',
            path='/foo/',
            params='',
            query='',
            fragment='')

Die Funktion urldefrag() gibt nun ein benanntes Tupel zurück.

>>> r = urllib.parse.urldefrag('https://pythonlang.de/about/#target')
>>> r
DefragResult(url='https://pythonlang.de/about/', fragment='target')
>>> r[0]
'https://pythonlang.de/about/'
>>> r.fragment
'target'

Und die Funktion urlencode() ist nun viel flexibler und akzeptiert entweder einen Zeichenketten- oder Bytes-Typ für das Argument query. Wenn es sich um eine Zeichenkette handelt, werden die Parameter safe, encoding und error an quote_plus() zur Kodierung gesendet.

>>> urllib.parse.urlencode([
...      ('type', 'telenovela'),
...      ('name', '¿Dónde Está Elisa?')],
...      encoding='latin-1')
'type=telenovela&name=%BFD%F3nde+Est%E1+Elisa%3F'

Wie in Parsing ASCII Encoded Bytes beschrieben, akzeptieren alle Funktionen von urllib.parse nun ASCII-kodierte Byte-Strings als Eingabe, solange diese nicht mit regulären Zeichenketten vermischt werden. Wenn ASCII-kodierte Byte-Strings als Parameter übergeben werden, sind die Rückgabetypen ebenfalls ASCII-kodierte Byte-Strings.

>>> urllib.parse.urlparse(b'https://pythonlang.de:80/about/')
ParseResultBytes(scheme=b'http', netloc=b'www.python.org:80',
                 path=b'/about/', params=b'', query=b'', fragment=b'')

(Arbeit von Nick Coghlan, Dan Mahn und Senthil Kumaran in bpo-2987, bpo-5468 und bpo-9873.)

mailbox

Dank einer konzertierten Anstrengung von R. David Murray wurde das Modul mailbox für Python 3.2 behoben. Die Herausforderung bestand darin, dass Mailbox ursprünglich mit einer Textoberfläche entwickelt wurde, E-Mail-Nachrichten jedoch am besten als bytes dargestellt werden, da verschiedene Teile einer Nachricht unterschiedliche Kodierungen haben können.

Die Lösung nutzte die binäre Unterstützung des Pakets email zum Parsen beliebiger E-Mail-Nachrichten. Darüber hinaus erforderte die Lösung eine Reihe von API-Änderungen.

Wie erwartet, akzeptiert die Methode add() für Objekte vom Typ mailbox.Mailbox nun binäre Eingaben.

StringIO und Texteingaben sind veraltet. Außerdem schlägt die String-Eingabe frühzeitig fehl, wenn Nicht-ASCII-Zeichen verwendet werden. Zuvor schlug sie fehl, wenn die E-Mail in einem späteren Schritt verarbeitet wurde.

Es gibt auch Unterstützung für die binäre Ausgabe. Die Methode get_file() gibt nun eine Datei im Binärmodus zurück (wo sie fälschlicherweise auf Textmodus gesetzt wurde). Es gibt auch eine neue Methode get_bytes(), die eine bytes-Darstellung einer Nachricht zurückgibt, die einem gegebenen Schlüssel entspricht.

Es ist immer noch möglich, nicht-binäre Ausgaben über die alte API-Methode get_string() zu erhalten, aber dieser Ansatz ist nicht sehr nützlich. Stattdessen ist es am besten, Nachrichten aus einem Message-Objekt zu extrahieren oder sie aus binärer Eingabe zu laden.

(Beigetragen von R. David Murray, mit Beiträgen von Steffen Daode Nurpmeso und einem anfänglichen Patch von Victor Stinner in bpo-9124.)

turtledemo

Der Demonstrationcode für das Modul turtle wurde aus dem Demo-Verzeichnis in die Hauptbibliothek verschoben. Er enthält über ein Dutzend Beispiel-Skripte mit lebhaften Anzeigen. Da er sich auf sys.path befindet, kann er nun direkt von der Kommandozeile ausgeführt werden.

$ python -m turtledemo

(Aus dem Demo-Verzeichnis verschoben von Alexander Belopolsky in bpo-10199.)

Multithreading

  • Der Mechanismus zur Serialisierung der Ausführung von gleichzeitig laufenden Python-Threads (allgemein bekannt als GIL oder Global Interpreter Lock) wurde neu geschrieben. Zu den Zielen gehörten vorhersagbarere Schaltintervalle und reduzierte Overhead durch Lock-Konflikte und die Anzahl der daraus resultierenden Systemaufrufe. Die Vorstellung eines "Prüfintervalls" zur Ermöglichung von Thread-Schaltungen wurde aufgegeben und durch eine absolute Dauer in Sekunden ersetzt. Dieser Parameter ist über sys.setswitchinterval() einstellbar. Er hat derzeit einen Standardwert von 5 Millisekunden.

    Weitere Details zur Implementierung sind in einer Nachricht der Mailingliste python-dev zu lesen (jedoch wurden die in dieser Nachricht aufgezeigten "Prioritätsanfragen" nicht zur Aufnahme beibehalten).

    (Beigetragen von Antoine Pitrou.)

  • Reguläre und rekursive Locks akzeptieren nun ein optionales Argument timeout für ihre Methode acquire(). (Beigetragen von Antoine Pitrou; bpo-7316.)

  • Ebenso erhielt threading.Semaphore.acquire() ein Argument timeout. (Beigetragen von Torsten Landschoff; bpo-850728.)

  • Reguläre und rekursive Lock-Erwerbe können nun durch Signale auf Plattformen, die Pthreads verwenden, unterbrochen werden. Das bedeutet, dass Python-Programme, die beim Erwerben von Locks blockieren, erfolgreich durch wiederholtes Senden von SIGINT an den Prozess (durch Drücken von Ctrl+C in den meisten Shells) beendet werden können. (Beigetragen von Reid Kleckner; bpo-8844.)

Optimierungen

Eine Reihe kleiner Leistungsverbesserungen wurden vorgenommen.

  • Der Peephole-Optimizer von Python erkennt nun Muster wie x in {1, 2, 3} als Test auf Mitgliedschaft in einer Menge von Konstanten. Der Optimizer wandelt die set in eine frozenset um und speichert die vordefinierte Konstante.

    Da die Geschwindigkeitsbuße nun weggefallen ist, ist es praktisch, Mitgliedschaftstests mit Set-Notation zu schreiben. Dieser Stil ist sowohl semantisch klar als auch operativ schnell.

    extension = name.rpartition('.')[2]
    if extension in {'xml', 'html', 'xhtml', 'css'}:
        handle(name)
    

    (Patch und zusätzliche Tests von Dave Malcolm; bpo-6690).

  • Das Serialisieren und Deserialisieren von Daten mit dem Modul pickle ist jetzt um ein Vielfaches schneller.

    (Beigetragen von Alexandre Vassalotti, Antoine Pitrou und dem Unladen Swallow-Team in bpo-9410 und bpo-3873.)

  • Der Timsort-Algorithmus, der in list.sort() und sorted() verwendet wird, läuft jetzt schneller und verbraucht weniger Speicher, wenn er mit einer Schlüsselfunktion aufgerufen wird. Zuvor wurde jedes Element einer Liste mit einem temporären Objekt umschlossen, das den für jedes Element zugeordneten Schlüsselwert speicherte. Jetzt werden zwei Arrays von Schlüsseln und Werten parallel sortiert. Dies spart den von den Sortier-Wrappern verbrauchten Speicher und die Zeit, die durch das Delegieren von Vergleichen verloren geht.

    (Patch von Daniel Stutzbach in bpo-9915.)

  • Die Leistung der JSON-Dekodierung wurde verbessert und der Speicherverbrauch reduziert, wenn derselbe String für mehrere Schlüssel wiederholt wird. Außerdem verwendet die JSON-Codierung jetzt die C-Geschwindigkeitsoptimierungen, wenn das Argument sort_keys wahr ist.

    (Beigetragen von Antoine Pitrou in bpo-7451 und von Raymond Hettinger und Antoine Pitrou in bpo-10314.)

  • Rekursive Sperren (erstellt mit der API threading.RLock()) profitieren jetzt von einer C-Implementierung, die sie so schnell wie reguläre Sperren macht und zwischen 10x und 15x schneller als ihre frühere reine Python-Implementierung ist.

    (Beigetragen von Antoine Pitrou; bpo-3001.)

  • Der Fast-Search-Algorithmus in stringlib wird nun von den Methoden split(), rsplit(), splitlines() und replace() auf Objekten vom Typ bytes, bytearray und str verwendet. Ebenso wird der Algorithmus von rfind(), rindex(), rsplit() und rpartition() verwendet.

    (Patch von Florent Xicluna in bpo-7622 und bpo-7462.)

  • Integer-zu-String-Konvertierungen arbeiten nun mit zwei "Ziffern" gleichzeitig, wodurch die Anzahl der Divisions- und Modulo-Operationen reduziert wird.

    (bpo-6713 von Gawain Bolton, Mark Dickinson und Victor Stinner.)

Es gab mehrere andere kleinere Optimierungen. Mengen-Differenzierung läuft jetzt schneller, wenn ein Operand wesentlich größer ist als der andere (Patch von Andress Bennetts in bpo-8685). Die Methode array.repeat() hat eine schnellere Implementierung (bpo-1569291 von Alexander Belopolsky). Der BaseHTTPRequestHandler hat eine effizientere Pufferung (bpo-3709 von Andrew Schaaf). Die Funktion operator.attrgetter() wurde beschleunigt (bpo-10160 von Christos Georgiou). Und ConfigParser lädt mehrzeilige Argumente etwas schneller (bpo-7113 von Łukasz Langa).

Unicode

Python wurde auf Unicode 6.0.0 aktualisiert. Die Aktualisierung des Standards fügt über 2.000 neue Zeichen hinzu, darunter Emoji-Symbole, die für Mobiltelefone wichtig sind.

Darüber hinaus hat der aktualisierte Standard die Zeicheneigenschaften für zwei Kannada-Zeichen (U+0CF1, U+0CF2) und ein New Tai Lue-Ziffernzeichen (U+19DA) geändert, wodurch die ersteren für die Verwendung in Bezeichnern in Frage kommen, während letzteres disqualifiziert wird. Weitere Informationen finden Sie unter Unicode Character Database Changes.

Codecs

Die Unterstützung für die arabische DOS-Kodierung *cp720* wurde hinzugefügt (bpo-1616979).

Die MBCS-Kodierung ignoriert das Fehlerbehandlungsargument nicht mehr. Im Standardmodus "strict" wird ein UnicodeDecodeError ausgelöst, wenn eine nicht dekodierbare Byte-Sequenz angetroffen wird, und ein UnicodeEncodeError für ein nicht kodierbares Zeichen.

Der MBCS-Codec unterstützt die Fehlerbehandler 'strict' und 'ignore' für die Dekodierung und 'strict' und 'replace' für die Kodierung.

Um die MBCS-Kodierung von Python 3.1 zu emulieren, wählen Sie den Handler 'ignore' für die Dekodierung und den Handler 'replace' für die Kodierung.

Unter Mac OS X dekodiert Python Kommandozeilenargumente mit 'utf-8' anstelle der Locale-Kodierung.

Standardmäßig verwendet tarfile unter Windows die Kodierung 'utf-8' (anstelle von 'mbcs') und den Fehlerbehandler 'surrogateescape' auf allen Betriebssystemen.

Dokumentation

Die Dokumentation wird weiter verbessert.

  • Eine Tabelle mit schnellen Links wurde am Anfang langer Abschnitte hinzugefügt, wie z. B. Built-in Functions. Im Fall von itertools werden die Links von Tabellen mit Cheatsheet-artigen Zusammenfassungen begleitet, um einen Überblick und eine Gedächtnisstütze zu bieten, ohne alle Dokumente lesen zu müssen.

  • In einigen Fällen kann der reine Python-Quellcode eine hilfreiche Ergänzung zur Dokumentation sein, daher enthalten nun viele Module schnelle Links zur neuesten Version des Quellcodes. Zum Beispiel hat die Dokumentation des Moduls functools am Anfang einen Link mit der Bezeichnung

    Source code Lib/functools.py.

    (Beigetragen von Raymond Hettinger; siehe Rationale.)

  • Die Dokumentation enthält nun mehr Beispiele und Rezepte. Insbesondere das Modul re hat einen ausführlichen Abschnitt, Regular Expression Examples. Ebenso wird das Modul itertools weiterhin mit neuen Itertools Recipes aktualisiert.

  • Das Modul datetime hat nun eine unterstützende Implementierung in reinem Python. Es wurden keine Funktionalitäten geändert. Dies bietet lediglich eine leichter lesbare alternative Implementierung.

    (Beigetragen von Alexander Belopolsky in bpo-9528.)

  • Das nicht mehr gewartete Verzeichnis Demo wurde entfernt. Einige Demos wurden in die Dokumentation integriert, einige in das Verzeichnis Tools/demo verschoben und andere wurden ganz entfernt.

    (Beigetragen von Georg Brandl in bpo-7962.)

IDLE

  • Das Menü "Format" enthält nun eine Option zum Bereinigen von Quelldateien durch Entfernen von nachgestellten Leerzeichen.

    (Beigetragen von Raymond Hettinger; bpo-5150.)

  • IDLE unter Mac OS X funktioniert nun sowohl mit Carbon AquaTk als auch mit Cocoa AquaTk.

    (Beigetragen von Kevin Walzer, Ned Deily und Ronald Oussoren; bpo-6075.)

Code-Repository

Zusätzlich zum bestehenden Subversion-Code-Repository unter https://svn.python.org gibt es nun ein Mercurial-Repository unter https://hg.python.org/.

Nach der Veröffentlichung von 3.2 ist geplant, auf Mercurial als primäres Repository umzusteigen. Dieses verteilte Versionskontrollsystem soll es den Community-Mitgliedern erleichtern, externe Changesets zu erstellen und zu teilen. Details finden Sie in PEP 385.

Um das neue Versionskontrollsystem zu erlernen, lesen Sie die Schnelleinstieg oder den Leitfaden zu Mercurial-Workflows.

Build- und C-API-Änderungen

Änderungen am Build-Prozess von Python und an der C-API umfassen

  • Die Skripte idle, pydoc und 2to3 werden nun mit einem versionsspezifischen Suffix bei der Ausführung von make altinstall installiert (bpo-10679).

  • Die C-Funktionen, die auf die Unicode-Datenbank zugreifen, akzeptieren und geben nun Zeichen aus dem vollen Unicode-Bereich zurück, selbst bei schmalen Unicode-Builds (Py_UNICODE_TOLOWER, Py_UNICODE_ISDECIMAL und andere). Ein sichtbarer Unterschied in Python ist, dass unicodedata.numeric() nun den korrekten Wert für große Code-Punkte zurückgibt, und repr() kann mehr Zeichen als druckbar betrachten.

    (Berichtet von Bupjoe Lee und behoben von Amaury Forgeot D’Arc; bpo-5127.)

  • Computed Gotos sind nun standardmäßig auf unterstützten Compilern aktiviert (die vom Konfigurationsskript erkannt werden). Sie können immer noch selektiv deaktiviert werden, indem --without-computed-gotos angegeben wird.

    (Beigetragen von Antoine Pitrou; bpo-9203.)

  • Die Option --with-wctype-functions wurde entfernt. Die integrierte Unicode-Datenbank wird nun für alle Funktionen verwendet.

    (Beigetragen von Amaury Forgeot D’Arc; bpo-9210.)

  • Hash-Werte sind nun vom Typ Py_hash_t, der so groß wie ein Pointer ist. Zuvor waren sie vom Typ `long`, der auf einigen 64-Bit-Betriebssystemen immer noch nur 32 Bit groß ist. Als Ergebnis dieser Korrektur können set und dict nun mehr als 2**32 Einträge auf Builds mit 64-Bit-Pointern enthalten (zuvor konnten sie bis zu dieser Größe wachsen, aber ihre Leistung verschlechterte sich katastrophal).

    (Vorgeschlagen von Raymond Hettinger und implementiert von Benjamin Peterson; bpo-9778.)

  • Ein neues Makro Py_VA_COPY kopiert den Zustand der variablen Argumentenliste. Es entspricht C99 va_copy, ist aber auf allen Python-Plattformen verfügbar (bpo-2443).

  • Eine neue C-API-Funktion PySys_SetArgvEx() ermöglicht es einem eingebetteten Interpreter, sys.argv festzuleulegen, ohne auch sys.path zu ändern (bpo-5753).

  • PyEval_CallObject() ist nun nur noch in Makroform verfügbar. Die Funktionsdeklaration, die aus Gründen der Abwärtskompatibilität beibehalten wurde, ist nun entfernt – das Makro wurde 1997 eingeführt (bpo-8276).

  • Es gibt eine neue Funktion PyLong_AsLongLongAndOverflow(), die analog zu PyLong_AsLongAndOverflow() ist. Beide dienen dazu, Python-`int`-Objekte in einen nativen, festen Datentyp umzuwandeln, wobei Fälle erkannt werden, in denen die Konvertierung nicht passt (bpo-7767).

  • Die Funktion PyUnicode_CompareWithASCIIString() gibt nun *ungleich* zurück, wenn der Python-String NUL-terminiert ist.

  • Es gibt eine neue Funktion PyErr_NewExceptionWithDoc(), die wie PyErr_NewException() ist, aber die Angabe eines Docstrings erlaubt. Dies ermöglicht C-Ausnahmen die gleiche Selbstdokumentationsfähigkeit wie ihre reinen Python-Pendants (bpo-7033).

  • Wenn mit der Option --with-valgrind kompiliert wird, wird der Pymalloc-Allocator automatisch deaktiviert, wenn er unter Valgrind läuft. Dies verbessert die Erkennung von Speicherlecks unter Valgrind, während Pymalloc zu anderen Zeiten genutzt wird (bpo-2422).

  • Das Format O? wurde aus den PyArg_Parse-Funktionen entfernt. Das Format wird nicht mehr verwendet und war nie dokumentiert (bpo-8837).

Es gab eine Reihe weiterer kleiner Änderungen an der C-API. Eine vollständige Liste finden Sie in der Datei Misc/NEWS.

Außerdem gab es eine Reihe von Aktualisierungen für den Mac OS X-Build. Details finden Sie in Mac/BuildScript/README.txt. Für Benutzer, die einen 32/64-Bit-Build verwenden, gibt es ein bekanntes Problem mit der Standard-Tcl/Tk-Version unter Mac OS X 10.6. Daher empfehlen wir die Installation einer aktualisierten Alternative wie ActiveState Tcl/Tk 8.5.9. Weitere Einzelheiten finden Sie unter https://pythonlang.de/download/mac/tcltk/.

Portierung auf Python 3.2

Dieser Abschnitt listet die zuvor beschriebenen Änderungen und andere Fehlerbehebungen auf, die möglicherweise Änderungen an Ihrem Code erfordern

  • Das Modul configparser wurde mehrfach überarbeitet. Die wichtigste Änderung ist der Ersatz der alten Klasse ConfigParser durch die seit langem bevorzugte Alternative SafeConfigParser. Darüber hinaus gibt es eine Reihe kleinerer Inkompatibilitäten.

    • Die Interpolationssyntax wird nun bei get()- und set()-Operationen validiert. Im Standard-Interpolationsschema sind nur zwei Token mit Prozentzeichen gültig: %(name)s und %%, wobei letzteres ein maskiertes Prozentzeichen ist.

    • Die Methoden set() und add_section() überprüfen nun, ob Werte tatsächliche Strings sind. Früher konnten unbeabsichtigt nicht unterstützte Typen eingeführt werden.

    • Doppelte Sektionen oder Optionen aus einer einzelnen Quelle lösen nun entweder DuplicateSectionError oder DuplicateOptionError aus. Früher überschrieben Duplikate lautlos einen vorherigen Eintrag.

    • Inline-Kommentare sind nun standardmäßig deaktiviert, sodass das Zeichen ; sicher in Werten verwendet werden kann.

    • Kommentare können nun eingerückt werden. Folglich müssen für ; oder # am Zeilenanfang in mehrzeiligen Werten diese interpoliert werden. Dies verhindert, dass Kommentar-Präfixzeichen in Werten fälschlicherweise als Kommentare interpretiert werden.

    • "" ist nun ein gültiger Wert und wird nicht mehr automatisch in einen leeren String umgewandelt. Für leere Strings verwenden Sie "option =" in einer Zeile.

  • Das Modul nntplib wurde umfassend überarbeitet, was bedeutet, dass seine APIs oft inkompatibel mit den APIs von 3.1 sind.

  • bytearray-Objekte können nicht mehr als Dateinamen verwendet werden; stattdessen sollten sie in bytes konvertiert werden.

  • Die Methoden array.tostring() und array.fromstring() wurden zur besseren Klarheit in array.tobytes() und array.frombytes() umbenannt. Die alten Namen sind veraltet. (Siehe bpo-8990.)

  • PyArg_Parse*() Funktionen

    • Das Format „t#“ wurde entfernt: Verwenden Sie stattdessen „s#“ oder „s*“.

    • Die Formate „w“ und „w#“ wurden entfernt: Verwenden Sie stattdessen „w*“.

  • Der Typ PyCObject, der in 3.1 als veraltet markiert wurde, wurde entfernt. Zum Umschließen von undurchsichtigen C-Pointern in Python-Objekten sollte die PyCapsule-API verwendet werden; der neue Typ verfügt über eine gut definierte Schnittstelle zur Übergabe von Typsicherheitsinformationen und eine weniger komplizierte Signatur für den Aufruf eines Destruktors.

  • Die Funktion sys.setfilesystemencoding() wurde entfernt, da sie ein fehlerhaftes Design hatte.

  • Die Funktion und Methode random.seed() salzen nun String-Seeds mit einer sha512-Hash-Funktion. Um auf die vorherige Version von seed zuzugreifen und Python 3.1-Sequenzen reproduzieren zu können, setzen Sie das Argument version auf 1, random.seed(s, version=1).

  • Die zuvor als veraltet markierte Funktion string.maketrans() wurde zugunsten der statischen Methoden bytes.maketrans() und bytearray.maketrans() entfernt. Diese Änderung löst die Verwirrung darüber, welche Typen vom Modul string unterstützt wurden. Jetzt haben str, bytes und bytearray jeweils ihre eigenen Methoden maketrans und translate mit dazwischenliegenden Übersetzungstabellen des entsprechenden Typs.

    (Beigetragen von Georg Brandl; bpo-5675.)

  • Die zuvor als veraltet markierte Funktion contextlib.nested() wurde zugunsten einer einfachen with-Anweisung entfernt, die mehrere Kontextmanager akzeptieren kann. Letztere Technik ist schneller (da sie integriert ist) und leistet bessere Arbeit bei der Finalisierung mehrerer Kontextmanager, wenn einer von ihnen eine Ausnahme auslöst.

    with open('mylog.txt') as infile, open('a.out', 'w') as outfile:
        for line in infile:
            if '<critical>' in line:
                outfile.write(line)
    

    (Beigetragen von Georg Brandl und Mattias Brändström; Appspot-Issue 53094.)

  • struct.pack() erlaubt nun nur noch Bytes für den Pack-Code s. Früher akzeptierte es Textargumente und kodierte sie implizit mit UTF-8 in Bytes. Dies war problematisch, da es Annahmen über die korrekte Kodierung traf und eine variable Kodierung fehlschlagen kann, wenn in ein festes Segment einer Struktur geschrieben wird.

    Code wie struct.pack('<6sHHBBB', 'GIF87a', x, y) sollte umgeschrieben werden, um Bytes anstelle von Text zu verwenden: struct.pack('<6sHHBBB', b'GIF87a', x, y).

    (Entdeckt von David Beazley und behoben von Victor Stinner; bpo-10783.)

  • Die Klasse xml.etree.ElementTree löst jetzt ein xml.etree.ElementTree.ParseError aus, wenn ein Parsen fehlschlägt. Zuvor wurde ein xml.parsers.expat.ExpatError ausgelöst.

  • Der neue, längere str()-Wert bei Gleitkommazahlen kann Doctests, die auf dem alten Ausgabeformat basieren, brechen.

  • In subprocess.Popen ist der Standardwert für close_fds unter Unix jetzt True; unter Windows ist er True, wenn die drei Standardströme auf None gesetzt sind, andernfalls False. Zuvor war close_fds standardmäßig immer False, was zu schwer lösbaren Fehlern oder Race Conditions führte, wenn offene Dateideskriptoren in den Kindprozess gelangen konnten.

  • Die Unterstützung für Legacy-HTTP 0.9 wurde aus urllib.request und http.client entfernt. Eine solche Unterstützung ist auf der Serverseite (in http.server) noch vorhanden.

    (Beigesteuert von Antoine Pitrou, bpo-10711.)

  • SSL-Sockets im Timeout-Modus lösen jetzt socket.timeout aus, wenn ein Timeout auftritt, anstatt eines generischen SSLError.

    (Beigesteuert von Antoine Pitrou, bpo-10272.)

  • Die irreführenden Funktionen PyEval_AcquireLock() und PyEval_ReleaseLock() wurden offiziell als veraltet markiert. Stattdessen sollten die Thread-State-bewussten APIs (wie PyEval_SaveThread() und PyEval_RestoreThread()) verwendet werden.

  • Aufgrund von Sicherheitsrisiken wurde asyncore.handle_accept() als veraltet markiert und eine neue Funktion, asyncore.handle_accepted(), wurde hinzugefügt, um sie zu ersetzen.

    (Beigesteuert von Giampaolo Rodola in bpo-6706.)

  • Aufgrund der neuen GIL-Implementierung kann PyEval_InitThreads() nicht mehr vor Py_Initialize() aufgerufen werden.