Python | |
---|---|
230px | |
Basisdaten | |
Paradigmen: | multiparadigmatisch |
Erscheinungsjahr: | 1991 |
Entwickler: | Python Software Foundation |
Aktuelle Version: | 3.1.1 (16. August 2009) 2.6.4 (25. Oktober 2009) |
Typisierung: | stark, dynamisch („Duck Typing“) |
Wichtige Implementierungen: | CPython, Jython, IronPython, PyPy |
Beeinflusst von: | ABC, Algol 60, Modula-3, Icon, C, Perl, LISP, Smalltalk, TCL, Haskell |
Beeinflusste: | Ruby, Boo, Groovy |
Lizenz: | Python License |
www.python.org |
Python [ˈpaɪθn̩] ist eine Programmiersprache, die mehrere Programmierparadigmen ermöglicht. So werden objektorientierte, aspektorientierte und funktionale Programmierung unterstützt.
Die Sprache wurde Anfang der 1990er Jahre von Guido van Rossum am Centrum voor Wiskunde en Informatica (Zentrum für Mathematik und Informatik) in Amsterdam als Nachfolger für die Programmier-Lehrsprache ABC entwickelt und war ursprünglich für das verteilte Betriebssystem Amoeba gedacht. Alle bisherigen Implementierungen der Sprache (siehe auch Jython oder Stackless Python) übersetzen den Text eines Python-Programms transparent in einen Zwischencode, der dann von einem Interpreter ausgeführt wird.
Der Name geht nicht etwa (wie das Logo vermuten ließe) auf die gleichnamige Schlangengattung (Pythons) zurück, sondern bezog sich ursprünglich auf die englische Komikertruppe Monty Python. In der Dokumentation finden sich daher auch einige Anspielungen auf Sketche aus dem Flying Circus.[1] Trotzdem etablierte sich die Assoziation zur Schlange, was sich unter anderem in der Programmiersprache Cobra[2] sowie dem Python-Toolkit „Boa“[3] äußert.
Python wurde mit dem Ziel entworfen, möglichst einfach und übersichtlich zu sein. Dies soll durch zwei Maßnahmen erreicht werden: Zum einen kommt die Sprache mit relativ wenigen Schlüsselwörtern aus[4], zum anderen ist die Syntax reduziert und auf Übersichtlichkeit optimiert. Dies führt dazu, dass Python eine Sprache ist, in der schnell und einfach programmiert werden kann. Sie ist daher besonders dort geeignet, wo Übersichtlichkeit und Lesbarkeit des Codes eine herausragende Rolle spielen – zum Beispiel in der Teamarbeit, bei Beschäftigung mit dem Quelltext nach längeren Pausen oder bei Programmieranfängern.
Durch die Möglichkeit, auch Programme anderer Sprachen als Modul einzubetten, werden viele Nischen in der Programmierung abgedeckt. Bei Bedarf lassen sich so beispielsweise zeitkritische Teile durch maschinennah in C programmierte Routinen ersetzen, oder Python kann als Skriptsprache eines anderen Programms dienen (Beispiele: OpenOffice.org, Blender, Cinema 4D, Maya, PyMOL, SPSS und GIMP).
Python ist eine Multiparadigmensprache. Das heißt, Python zwingt den Programmierer nicht zu einem einzigen bestimmten Programmierparadigma, sondern erlaubt es, das für die jeweilige Aufgabe am besten geeignete Paradigma zu wählen. Objektorientierte und strukturierte Programmierung werden vollständig unterstützt, weiterhin gibt es Spracheigenschaften für funktionale und aspektorientierte Programmierung.
Die Datentypen werden dynamisch verwaltet; eine statische Typprüfung (wie z. B. bei C++) gibt es nicht. Die Freigabe nicht mehr benutzter Speicherbereiche erfolgt durch automatische Speicherbereinigung (garbage collection). Unicode-Unterstützung existiert seit Version 2.0.
In Version 2.6 bis 2.6.3 können sich Entwickler mit dem Kommandozeilenparameter „-3“ alle Konstrukte in ihrem Code anzeigen lassen, die es ab Python 3.0 nicht mehr gibt.[5]
Python besitzt eine größere Anzahl von grundlegenden Datentypen. Neben der herkömmlichen Ganzzahl- und Gleitkommaarithmetik unterstützt es transparent auch beliebig große Ganzzahlen und komplexe Zahlen.
Es verfügt über die übliche Ausstattung an Zeichenkettenoperationen. Zeichenketten sind in Python allerdings unveränderliche Objekte (wie auch in Java). Damit führen Operationen, die das Ändern einer Zeichenkette bewerkstelligen sollen – wie z. B. das Ersetzen von Zeichen – dazu, dass stattdessen eine neue Zeichenkette zurückgegeben wird.
In Python ist der Datentyp an das Objekt (den Wert) gebunden und nicht an eine Variable, d. h. Datentypen werden dynamisch vergeben, so wie bei Smalltalk oder LISP – und nicht wie bei Java. Alle Werte werden per Referenz übergeben. In Python ist alles ein Objekt; Klassen, Typen, Methoden, Module etc.
Trotz der dynamischen Typverwaltung enthält Python eine gewisse Typprüfung. Diese ist strenger als bei Perl, aber weniger strikt als etwa bei Objective CAML. Implizite Umwandlungen nach dem Duck-Typing-Prinzip sind unter Anderem für numerische Typen definiert, so dass man beispielsweise eine komplexe Zahl mit einer langen Ganzzahl ohne explizite Typumwandlung multiplizieren kann. Anders als bei Perl gibt es allerdings keine implizite Umwandlung zwischen Zahlen und Zeichenketten; in Operationen für Zeichenketten kann also anstelle einer Zeichenkette nicht direkt eine Zahl verwendet werden. Der Operator == überprüft zwei Objekte auf (Wert-)Gleichheit. Der Operator is überprüft die tatsächliche Identität zweier Objekte.[6]
Python besitzt mehrere Sammeltypen, darunter Listen, Tupel, Mengen (Sets) und Wörterbücher (Dictionaries). Listen, Tupel und Zeichenketten sind Folgen (Sequenzen, Arrays) und kennen fast alle die gleichen Methoden: Über die Zeichen einer Kette kann man ebenso iterieren wie über die Elemente einer Liste. Listen sind erweiterbare Felder (Arrays), wohingegen Tupel eine feste Länge haben und unveränderlich sind.
Der Zweck solcher Unveränderlichkeit hängt mit den Wörterbüchern zusammen, ein Datentyp, der auch als assoziatives Array bezeichnet wird. Um auch unter den Bedingungen der Übergabe per Referenz die Datenkonsistenz zu sichern, müssen die Schlüssel eines Wörterbuches vom Typ „unveränderlich“ sein. Die ins Wörterbuch eingetragenen Werte können dagegen von beliebigem Typ sein.
Sets sind Mengen von Objekten und in CPython ab Version 2.4 im Standardsprachumfang enthalten. Diese Datenstruktur kann beliebige (paarweise unterschiedliche) Objekte aufnehmen und stellt Mengenoperationen wie beispielsweise Durchschnitt, Differenz und Vereinigung zur Verfügung.
Das Typsystem von Python ist auf das Klassensystem abgestimmt. Obwohl die eingebauten Datentypen genau genommen keine Klassen sind, können Klassen von einem Typ erben. So kann man die Eigenschaften von Zeichenketten oder Wörterbüchern erweitern – auch von Ganzzahlen. Python unterstützt daneben Mehrfachvererbung.
Die Sprache unterstützt direkt den Umgang mit Typen und Klassen. Typen können ausgelesen (ermittelt) und verglichen werden und verhalten sich wie Objekte – in Wirklichkeit sind die Typen (wie in Smalltalk) selbst ein Objekt. Die Attribute eines Objektes können als Wörterbuch extrahiert werden.
Eines der Entwurfsziele für Python war die gute Lesbarkeit des Quellcodes. Die Anweisungen benutzen häufig englische Schlüsselwörter, wo andere Sprachen Symbole einsetzen. Darüber hinaus besitzt Python weniger syntaktische Konstruktionen als viele andere strukturierte Sprachen wie C, Perl oder Pascal:
for
zur Iteration über die Elemente einer Sequenzwhile
zur Wiederholung einer Schleife, solange ein logischer Ausdruck wahr ist.if … elif … else
für VerzweigungenBeim letzten Punkt bieten andere Programmiersprachen zusätzlich switch
und/oder goto
. Diese wurden zugunsten der Lesbarkeit in Python weggelassen und müssen durch if
-Konstrukte oder andere Verzweigungsmöglichkeiten (Slices, Wörterbücher) abgebildet werden.
Python benutzt wie Miranda und Haskell Einrückungen als Strukturierungselement. Diese Idee wurde erstmals von Peter J. Landin vorgeschlagen und von ihm off-side rule („Abseitsregel“) genannt. In den meisten anderen Programmiersprachen werden Blöcke durch Klammern oder Schlüsselworte markiert, während verschieden große Leerräume außerhalb von Zeichenketten keine spezielle Semantik tragen. Bei diesen Sprachen ist die Einrückung zur optischen Hervorhebung eines Blockes zwar erlaubt und in der Regel auch erwünscht, aber nicht vorgeschrieben. Für Programmierneulinge wird der Zwang zu lesbarem Stil aber als Vorteil gesehen.
Hierzu ein kurzes Beispiel: Hier sind Funktionen in C und in Python, die das gleiche ausführen – die Fakultät einer Ganzzahl berechnen.
Fakultätsfunktion in C (ohne Einrückung):
int fakultaet(int x) {if (x > 1) return x * fakultaet(x - 1); else return 1;}
Fakultätsfunktion in C (mit Einrückung):
int fakultaet(int x)
{
if (x > 1)
return x * fakultaet(x - 1);
else
return 1;
}
Jetzt die gleiche Funktion in Python:
def fakultaet(x):
if x > 1:
return x * fakultaet(x - 1)
else:
return 1
Es ist jedoch darauf zu achten, die Einrückungen im gesamten Programmtext gleich zu gestalten. Die gemischte Verwendung von Leerzeichen und Tabulatorzeichen kann zu Problemen führen, da für den Pythoninterpreter ein Tabulator äquivalent zu acht Leerzeichen behandelt wird. Editoren ohne Pythonunterstützung stellen einen Tabulator meist optisch als weniger als acht Leerzeichen dar, was zu Syntaxfehlern oder ungewollter Programmstrukturierung führen kann. Pythonfähige Editoren ersetzen in der Regel als vorbeugende Maßnahme alle Tabulatoren durch eine feste Anzahl Leerzeichen.
Ausdrucksstarke syntaktische Elemente zur funktionalen Programmierung vereinfachen das Arbeiten mit Listen und anderen Sammeltypen. Eine solche Vereinfachung ist die Listennotation, die aus der funktionalen Programmiersprache Haskell stammt; hier bei der Berechnung der ersten fünf Zweierpotenzen:
zahlen = [1, 2, 3, 4, 5]
zweierpotenzen = [2 ** n for n in zahlen]
Weil in Python Funktionen als Argumente auftreten dürfen, kann man auch ausgeklügeltere Konstruktionen ausdrücken, wie den Continuation-passing style.
Pythons Schlüsselwort lambda könnte manche Anhänger der funktionalen Programmierung fehlleiten. Solche lambda-Blöcke in Python können nur Ausdrücke enthalten, aber keine Anweisungen. Damit sind sie nicht der allgemeinste Weg, um eine Funktion zurückzugeben. Die übliche Vorgehensweise ist stattdessen, den Namen einer lokalen Funktion zurückzugeben. Das folgende Beispiel zeigt dies anhand einer einfachen Funktion nach den Ideen von Haskell Brooks Curry:
def add_and_print_maker(x):
def temp(y):
print("{} + {} = {}".format(x, y, x + y))
return temp
Damit ist auch Currying auf einfache Art möglich, um generische Funktionsobjekte auf problemspezifische herunterzubrechen. Hier ein einfaches Beispiel:
def curry(func, knownargument):
return lambda unknownargument: func(unknownargument, knownargument)
Wird die curry-Funktion aufgerufen, erwartet diese eine Funktion mit zwei notwendigen Parametern sowie die Parameterbelegung für den zweiten Parameter dieser Funktion. Der Rückgabewert von curry ist eine Funktion, die dasselbe tut wie func aber nur noch einen Parameter benötigt.
Anonyme Namensräume (sog. Closures) sind mit den o.g. Mechanismen in Python ebenfalls einfach möglich. Ein simples Beispiel für einen Stack, intern durch eine Liste repräsentiert:
def stack():
l = []
def pop(): return l.pop()
def push(element): l.append(element)
def isempty(): return len(l) == 0
return pop, push, isempty
POP, PUSH, ISEMPTY = stack()
Auf diese Weise erhält man die drei Funktionsobjekte POP, PUSH, ISEMPTY, um den Stack zu modifizieren bzw. auf enthaltene Elemente zu prüfen, ohne l direkt modifizieren zu können.
Python nutzt ausgiebig die Ausnahmebehandlung (engl. exception handling) als ein Mittel, um Fehlerbedingungen zu testen. Dies ist so weit in Python integriert, dass es sogar möglich ist, Syntaxfehler abzufangen und zur Laufzeit zu behandeln.
Ausnahmen haben einige Vorteile gegenüber anderen beim Programmieren üblichen Verfahren der Fehlerbehandlung (wie z.B. Fehler-Rückgabewerte und globale Statusvariablen). Sie sind Thread-sicher und können leicht bis in die höchste Programmebene weitergegeben oder an einer beliebigen anderen Ebene der Funktionsaufruffolge behandelt werden. Der korrekte Einsatz von Ausnahmebehandlungen beim Zugriff auf dynamische Ressourcen erleichtert es zudem, bestimmte auf Race Conditions basierende Sicherheitslücken zu vermeiden, die entstehen können, wenn Zugriffe auf bereits veralteten Statusabfragen basieren.
Der Python-Ansatz legt den Einsatz von Ausnahmen nahe, wann immer eine Fehlerbedingung entstehen könnte. Nützlich ist dieses Prinzip beispielsweise bei der Konstruktion robuster Eingabeaufforderungen:
while True:
try:
num = input("Eine Zahl eingeben: ")
num = int(num)
break
except ValueError:
print("Eine _Zahl_, bitte!")
Dieser Code wird den Benutzer so lange nach einer Nummer fragen, bis dieser eine Zeichenfolge eingibt, die sich per int() in eine Ganzzahl konvertieren lässt. Durch die Ausnahmebehandlung wird hier vermieden, dass eine Fehleingabe zu einem Laufzeitfehler führt, der das Programm zur Beendigung zwingt.
Ebenso kann auch das hier nicht berücksichtigte Interrupt-Signal (SIGINT, häufig Strg+C) mittels Ausnahmebehandlung in Python abgefangen und behandelt werden (except KeyboardInterrupt: …).
Python verfügt über eine große Standardbibliothek, wodurch es sich für viele Anwendungen gut eignet. Sie ist eine der größten Stärken von Python. Das meiste davon ist plattformunabhängig, so dass auch größere Python-Programme oft auf Unix, Windows, Mac OS X und anderen Plattformen ohne Änderung laufen. Die Module der Standardbibliothek können mit in C oder Python selbst geschriebenen Modulen ergänzt werden.
Die Standardbibliothek ist besonders auf Internet-Anwendungen zugeschnitten, mit der Unterstützung einer großen Anzahl von Standardformaten und -Protokollen (wie MIME und HTTP). Module zur Schaffung grafischer Schnittstellen, zur Verbindung mit relationalen Datenbanken und zur Manipulation regulärer Ausdrücke sind ebenfalls enthalten.
Mit Hilfe des mitgelieferten Moduls Tkinter kann in Python (wie in Perl und Tcl) schnell eine grafische Oberfläche (GUI) mit Tk erzeugt werden. Es gibt darüber hinaus eine Vielzahl von weiteren Wrappern von anderen Anbietern. Sie stellen Anbindungen (engl. language bindings) zu GUI-Bibliotheken anderer Programmiersprachen wie z. B. PyGTK, PyQt, PyKDE, wxPython, PyObjC und PyFLTK zur Verfügung.
Als nicht triviales Beispiel sei hier der Quicksort-Algorithmus angegeben:
def quicksort(liste):
if len(liste) <= 1:
return liste
pivotelement = liste.pop()
links = [element for element in liste if element < pivotelement]
rechts = [element for element in liste if element >= pivotelement]
return quicksort(links) + [pivotelement] + quicksort(rechts)
Hier ermöglicht insbesondere die Listennotation für die Variablen links und rechts eine kompakte Darstellung. Zum Vergleich eine imperative Formulierung dieser zwei Zeilen:
...
links, rechts = [], [] # Leere Listen links und rechts
pivotelement = liste.pop() # Das letzte Element aus der Liste nehmen
for element in liste: # Die verkürzte Liste durchlaufen
if element < pivotelement:
links.append(element) # wenn < dann an linke Liste anhängen
else:
rechts.append(element) # wenn nicht < (also >=) dann an rechte Liste anhängen
...
So wie LISP, Ruby, Groovy – und Perl im Debugger – unterstützt der Python-Interpreter auch einen interaktiven Modus, in dem Ausdrücke am Terminal eingegeben und die Ergebnisse sofort betrachtet werden können. Das ist nicht nur für Neulinge, die die Sprache lernen, angenehm, sondern auch für erfahrene Programmierer: Code-Stückchen können interaktiv ausgiebig getestet werden, bevor man sie in ein geeignetes Programm aufnimmt.
Darüber hinaus steht mit PyShell ein Kommandozeileninterpreter für verschiedene unixoide Computer-Betriebssysteme zur Verfügung, der neben klassischen Unix-Shellkommandos auch direkte Eingaben in Python-Form verarbeiten kann.
Es existieren einige spezielle Entwicklungsumgebungen für Python, beispielsweise Eric Python IDE. Des Weiteren existieren Plugins für größere IDEs wie Eclipse und Netbeans. Texteditoren für Programmierer wie Vim und Emacs lassen sich gegebenenfalls auch für Python anpassen.
<ref>
-Tag. Der Name „shootout-php“ wurde mehrere Male mit einem unterschiedlichen Inhalt definiert.