Umschlungen
Zwar ist Version 2.4 der Scriptsprache Python nicht so spektakulär, wie die 2.3 es war, aber Entwickler dürften auf viel Brauchbares und etliche Vereinfachungen stoßen. In Sachen Performance gibt es ebenfalls Fortschritte.
- Thomas Kaufmann
Pythons Version 2.4 ist kein solcher Quantensprung wie 2.3, vielmehr liegt der Fokus auf Stabilisierung, Vereinfachung und Bugfixing sowie Performance-Tuning. Einige Standardmodule (wie sets, heapq) haben die Entwickler aus Effizienz-GrĂĽnden in C reimplementiert, was selbstredend fĂĽr mehr Geschwindigkeit sorgt. Des Weiteren gibt es reichlich Optimierungen beim Interpreter. So gelang es, die inneren Schleifen fĂĽr list- und tuple-slicing zu optimieren, mit dem Ergebnis, dass sie jetzt circa ein Drittel schneller als vorher ablaufen. FĂĽr dictionaries gilt dasselbe: Hier ist dank der Anpassungen ebenso ein Performance-Gewinn bei den Funktionen keys(), values(), items(), iterkeys(), itervalues() und iteritems() zu verzeichnen.
Außerdem sind die Algorithmen für das Listen-Handling entscheidend verbessert (für wachsende und schrumpfende Listen). Erreicht wurde dies unter anderem durch die eingeschränkte Nutzung des Systemaufrufs realloc(). Dieser Umstand schlägt sich in der Ausführungsgeschwindigkeit von L.append() und L.pop() spürbar nieder. Auch die List Comprehensions, eingeführt mit Python 2.0, profitieren hiervon (etwa der Aufruf list.extend()). Dass es zu den genannten Verbesserungen kam, ist der Einführung von LIST_APPEND (Opcode) zu verdanken, denn dadurch gelang es, den generierten Bytecode zu vereinfachen, was wiederum zu mehr Tempo führt.
Listen und Kollektionen
Online-Ressourcen
Python Enhancement Proposals (PEPs) kann jedermann einreichen (www.python.org/peps/); sie sind durchnummeriert. PEP 237 betrifft die interne Vereinheitlichung von Long Integer und Integer. Python 2.3 gab bei bestimmten Integer-Operationen eine Warnung aus und nur limitierte Werte als Ergebnis (32 oder 64 Bit, je nach Plattform). Die neue Version liefert stattdessen den tatsächlichen Wert zurück: einen Long Integer.
Ebenfalls interessant ist PEP 289. Schon Python 2.2 enthielt das fĂĽr Generator Expressions wichtige iterator-Konzept und vereinfachte das Durchlaufen groĂźer Sequenzen. Ăśberdies konnte der Entwickler fortan durch den iterator Code im funktionalen Programmierstil schreiben.
Generator Expressions funktionieren im Prinzip ähnlich List Comprehensions, mit der Ausnahme, dass sie nicht die gesamte Sequenz in den Speicher laden. Vielmehr liefert ein geladenes Generator-Objekt die Elemente einzeln zurück. Grundsätzlich stehen Generator Expressions in runden Klammern; damit lässt sich eine Generator Expression an eine herkömmliche Built-in-Funktion übergeben:
print sum(obj.count for obj in list_all_objects())
Und es gibt noch einen wichtigen Unterschied zwischen Generator Expression und List Comprehension: Die Schleifenvariable obj im obigen Code-Snippet ist außerhalb des Generator-Ausdrucks nicht zugänglich. Bei einer List Comprehension enthielte die Schleifenvariable obj aber den letzten ihr zugewiesenen Wert. In künftigen Python-Versionen sollen List Comprehensions sich allerdings in dieser Beziehung wie Generator Expressions verhalten.
Einige Module der Standard-Bibliothek wurden grundlegend ĂĽberarbeitet oder neu implementiert. Hier folgen ein paar wichtige. Das curses-Modul unterstĂĽtzt jetzt die ncurses-Erweiterung use_default_colors(). Dadurch kann man mit einem transparenten Hintergrund arbeiten (auf Plattformen, die transparenten Terminal-Support bieten). Und in der Standardbibliothek haben die Entwickler das bisect-Modul in C reimplementiert.
Erfreulicherweise gibt es ein neues Collections-Modul; momentan enthält es nur den Typ deque (eine double-ended Queue), der effizient das Hinzufügen und Entfernen von Elementen an beiden Enden erlaubt. Listing 1 demonstriert die Verwendung. Viele andere Module profitieren von collections.deque, insbesondere Queue und die für die Nebenläufigkeit (beispielsweise Threading).
Listing 1: Collection-Modul
>>> from collections import deque
>>> d = deque('ghi') # Konstruktor
>>> d.append('j') # Element rechts einfĂĽgen
>>> d.appendleft('f') # Element links einfĂĽgen
>>> d
deque(['f', 'g', 'h', 'i', 'j'])
>>> d.pop() # das rechte Elemente ausgeben
'j'
>>> d.popleft()
'f'
>>> list(d) # deque als Liste ausgeben
['g', 'h', 'i']
>>> 'h' in d # deque nach Element absuchen
True
Modulares: WWW und E-Mail
Bei den Modulen zu WWW und E-Mail der Standardbibliothek gibt es ebenfalls manches Neue beziehungsweise erfreuliche Veränderungen. Der IMAP4-Client (Modul imaplib) unterstützt mittlerweile das THREAD-Kommando; die Methoden deleteacl() und myrights() sind neu dazu gekommen. Mit poplib kann man jetzt Mails via SSL abholen. Das nntplib-Modul (ein News-Client) kapselt die NNTP-Klasse. Die ist um die Methoden description() und descriptions() erweitert, was Beschreibungen für eine einzelne beziehungsweise mehrere Gruppen bewirkt. Eine Multi-Call-Erweiterung bietet xmlrpclib, die es erlaubt, mehrere XML-RPC-Aufrufe gleichzeitig in einem einzigen HTTP-Request absetzen zu können.
Ein neues Modul namens cookielib bietet dem Entwickler clientseitigen Support fĂĽr HTTP-Cookies. Vom Webserver angebotene Cookies landen in so genannten cookie jars, die bei Bedarf wieder ausgelesen werden. Ein Policy-Objekt ĂĽberwacht diesen Vorgang. Das Standardmodul urllib2 kann schon mit cookielib interagieren.
Interessant sind zwei neue Funktionen des operator-Moduls: attrgetter(attr) sowie itemgetter(index), die sich dazu eignen, auf einfache Weise Daten aus Listen zu extrahieren. Mit einer Verbesserung wartet auch das profile-Modul auf: Entwickler können jetzt die Laufzeit von C-Erweiterungen prüfen.
Bei regulären Ausdrücken gibt es ebenfalls ein Novum, denn das re-Modul ist um bedingte Ausdrücke erweitert. Im Statement
(?(group)A|B)
ist group entweder eine numerische Gruppen-ID beziehungsweise ein früher definierter Gruppenname (?P<group>...). Falls group einen Treffer liefert, wird A mit dem String verglichen, sonst mit B. Perl/Java/C/C++-Entwicklern sollte diese Art Bedingung vertraut vorkommen (der ternäre Operator lässt grüßen).
Änderungen am Sprachkern
Zum Schluss einige den Sprachkern betreffende Veränderungen: dict.update() akzeptiert nun dieselbe Initialisierungsform wie der mit Python 2.3 eingeführte dict()-Konstruktor. Im string-Modul können die Methoden ljust(), rjust() und center() ein optionales Argument für Füll-Zeichen (bisher war nur ein Leerzeichen erlaubt) aufnehmen. Und die neu hinzugekommenen Methoden rsplit() arbeiten analog zu split(), beginnen allerdings am Ende der Zeichenkette.
sort() kann nun drei neue (optionale) Schlüsselwort-Argumente bekommen: cmp, key und reverse - das erleichtert den Umgang mit Listen beträchtlich. Folgender Code demonstriert die Verwendung des Schlüsselwortes key:
>> L = ['A', 'b', 'c', 'D']
>> L.sort()() # Case-sensitive
>> L
['A', 'D', 'b', 'c']
>> L.sort(key=str.lower)
>> L ['A', 'b', 'c', 'D']
zip() liefert neuerdings - falls ohne Argumente aufgerufen - eine leere Liste zurück. Bislang warf es im Falle fehlender Argumente eine Exception aus. Das ist gerade für Argumente mit variabler Länge durchaus von Vorteil.
Zum Datentyp NoneType gibt es nur ein einziges Literal: None. Dies hat sich zu einer Konstante gemausert; falls jemand versucht, einem Bezeichner None einen Wert zuzuweisen, hat das einen Syntax-Error zur Folge.
Fazit
Generell lässt sich konstatieren, dass man im Python-Lager dieser Tage recht umtriebig ist. Die neue Version bietet einen optimierten Interpreter, schließt Lücken (durch neue Typen, siehe Collections) und bietet ein verbessertes Laufzeitverhalten. Und Python steht ja nicht umsonst im Ruf, eine produktive Sprache zu sein.
Weitere Stichworte sind in diesem Kontext Zope 3, Jython sowie Iron Python. Bei Letzterem handelt es sich um den jüngsten Coup von Jim Hugunin (dem Jython-Autor); Iron Python ist eine Python-Variante für die .Net-Plattform. Unlängst hat Microsoft Hugunin eingestellt, um seine Tätigkeit dort weiterzuführen. Das lässt für die mittelbare Zukunft auf innovative Software hoffen.
Thomas Kaufmann
ist freier Python/Zope-Entwickler sowie Datenbank-Administrator und arbeitet als IT-Consultant fĂĽr mehrere Berliner Firmen.
Literatur
[1] Rainer Fischbach; Scriptsprachen; Weite Serpentinen; Python-Neuerungen in den Versionen 2.2 und 2.3; iX 10/2003, S. 76 (hb)