1. Einführung¶
Dieses Referenzhandbuch beschreibt die Programmiersprache Python. Es ist nicht als Tutorial gedacht.
Während ich versuche, so präzise wie möglich zu sein, habe ich mich dafür entschieden, für alles außer der Syntax und der lexikalischen Analyse einfaches Englisch statt formaler Spezifikationen zu verwenden. Dies sollte das Dokument für den durchschnittlichen Leser verständlicher machen, lässt jedoch Raum für Mehrdeutigkeiten. Wenn Sie also vom Mars kämen und versuchten, Python allein anhand dieses Dokuments neu zu implementieren, müssten Sie unter Umständen Dinge erraten und würden am Ende wahrscheinlich eine ganz andere Sprache implementieren. Wenn Sie hingegen Python verwenden und sich fragen, wie die genauen Regeln für einen bestimmten Bereich der Sprache lauten, sollten Sie diese hier definitiv finden können. Wenn Sie eine formalere Definition der Sprache wünschen, könnten Sie vielleicht Ihre Zeit opfern — oder eine Klonmaschine erfinden :-).
Es ist gefährlich, einem Sprachreferenzdokument zu viele Implementierungsdetails hinzuzufügen — die Implementierung kann sich ändern, und andere Implementierungen derselben Sprache können anders funktionieren. Andererseits ist CPython die am weitesten verbreitete Python-Implementierung (obwohl alternative Implementierungen weiter an Unterstützung gewinnen), und ihre speziellen Eigenheiten sind es manchmal wert, erwähnt zu werden, insbesondere dort, wo die Implementierung zusätzliche Einschränkungen mit sich bringt. Daher finden sich im gesamten Text verstreut kurze „Implementierungshinweise“.
Jede Python-Implementierung bringt eine Reihe von eingebauten und Standard-Modulen mit. Diese sind in The Python standard library dokumentiert. Einige wenige eingebaute Module werden erwähnt, wenn sie in wesentlicher Weise mit der Sprachdefinition interagieren.
1.1. Alternative Implementierungen¶
Obwohl es eine Python-Implementierung gibt, die bei weitem am beliebtesten ist, gibt es einige alternative Implementierungen, die für verschiedene Zielgruppen von besonderem Interesse sind.
Zu den bekannten Implementierungen gehören:
- CPython
Dies ist die ursprüngliche und am meisten gepflegte Implementierung von Python, geschrieben in C. Neue Sprachmerkmale erscheinen hier in der Regel zuerst.
- Jython
Python implementiert in Java. Diese Implementierung kann als Skriptsprache für Java-Anwendungen verwendet werden oder zur Erstellung von Anwendungen unter Verwendung der Java-Klassenbibliotheken dienen. Sie wird auch häufig verwendet, um Tests für Java-Bibliotheken zu schreiben. Weitere Informationen sind auf der Jython-Website zu finden.
- Python for .NET
Diese Implementierung verwendet tatsächlich die CPython-Implementierung, ist jedoch eine verwaltete .NET-Anwendung und stellt .NET-Bibliotheken zur Verfügung. Sie wurde von Brian Lloyd entwickelt. Weitere Informationen finden Sie auf der Python for .NET-Startseite.
- IronPython
Ein alternatives Python für .NET. Im Gegensatz zu Python.NET ist dies eine vollständige Python-Implementierung, die IL generiert und Python-Code direkt in .NET-Assemblies kompiliert. Sie wurde von Jim Hugunin, dem ursprünglichen Schöpfer von Jython, entwickelt. Weitere Informationen finden Sie auf der IronPython-Website.
- PyPy
Eine vollständig in Python geschriebene Implementierung von Python. Sie unterstützt verschiedene fortgeschrittene Funktionen, die in anderen Implementierungen nicht zu finden sind, wie etwa Stackless-Unterstützung und einen Just-in-Time-Compiler. Eines der Ziele des Projekts ist es, zum Experimentieren mit der Sprache selbst anzuregen, indem es einfacher gemacht wird, den Interpreter anzupassen (da er in Python geschrieben ist). Weitere Informationen sind auf der Startseite des PyPy-Projekts verfügbar.
Jede dieser Implementierungen weicht in irgendeiner Weise von der in diesem Handbuch dokumentierten Sprache ab oder führt spezifische Informationen über das hinaus ein, was in der Standard-Python-Dokumentation behandelt wird. Bitte ziehen Sie die implementierungsspezifische Dokumentation zurate, um zu erfahren, was Sie sonst noch über die von Ihnen verwendete Implementierung wissen müssen.
1.2. Notation¶
Die Beschreibungen der lexikalischen Analyse und Syntax verwenden eine Grammatik-Notation, die eine Mischung aus EBNF und PEG ist. Zum Beispiel:
name:letter(letter|digit| "_")* letter: "a"..."z" | "A"..."Z" digit: "0"..."9"
In diesem Beispiel besagt die erste Zeile, dass ein name ein letter ist, gefolgt von einer Sequenz aus null oder mehr lettern, digits und Unterstrichen. Ein letter wiederum ist ein beliebiges Einzelzeichen von 'a' bis 'z' sowie A bis Z, ein digit ist ein Einzelzeichen von 0 bis 9.
Jede Regel beginnt mit einem Namen (der die zu definierende Regel identifiziert), gefolgt von einem Doppelpunkt, :. Die Definition rechts vom Doppelpunkt verwendet die folgenden Syntaxelemente:
name: Ein Name verweist auf eine andere Regel. Wo möglich, handelt es sich um einen Link zur Definition der Regel.TOKEN: Ein in Großbuchstaben geschriebener Name verweist auf ein Token. Für die Zwecke von Grammatikdefinitionen sind Tokens dasselbe wie Regeln.
"text",'text': Text in einfachen oder doppelten Anführungszeichen muss buchstäblich (ohne die Anführungszeichen) übereinstimmen. Die Art der Anführungszeichen wird entsprechend der Bedeutung vontextgewählt:'if': Ein Name in einfachen Anführungszeichen kennzeichnet ein Schlüsselwort."case": Ein Name in doppelten Anführungszeichen kennzeichnet ein Soft-Schlüsselwort.'@': Ein Symbol, das kein Buchstabe ist, in einfachen Anführungszeichen kennzeichnet einOP-Token, das heißt ein Trennzeichen oder einen Operator.
e1 e2: Elemente, die nur durch Leerzeichen getrennt sind, bezeichnen eine Sequenz. Hier musse1vone2gefolgt werden.e1 | e2: Ein senkrechter Strich wird verwendet, um Alternativen zu trennen. Er bezeichnet PEGs „geordnete Auswahl“ (ordered choice): Wenne1passt, wirde2nicht berücksichtigt. In traditionellen PEG-Grammatiken wird dies als Schrägstrich,/, anstelle eines senkrechten Strichs geschrieben. Siehe PEP 617 für weitere Hintergründe und Details.e*: Ein Stern bedeutet null oder mehr Wiederholungen des vorhergehenden Elements.e+: Ebenso bedeutet ein Plus ein oder mehr Wiederholungen.[e]: Ein in eckige Klammern eingeschlossener Ausdruck bedeutet null oder ein Vorkommen. Mit anderen Worten: Der eingeschlossene Ausdruck ist optional.e?: Ein Fragezeichen hat exakt dieselbe Bedeutung wie eckige Klammern: Das vorhergehende Element ist optional.(e): Runde Klammern werden zur Gruppierung verwendet.
Die folgende Notation wird nur in lexikalischen Definitionen verwendet.
"a"..."z": Zwei Literalzeichen, die durch drei Punkte getrennt sind, bedeuten die Auswahl eines beliebigen Einzelzeichens im angegebenen (inklusiven) Bereich von ASCII-Zeichen.<...>: Ein Ausdruck in spitzen Klammern liefert eine informelle Beschreibung des passenden Symbols (zum Beispiel<any ASCII character except "\">) oder eine Abkürzung, die im umgebenden Text definiert ist (zum Beispiel<Lu>).
Einige Definitionen verwenden auch Lookaheads, die angeben, dass ein Element an einer bestimmten Position passen muss (oder nicht passen darf), jedoch ohne eine Eingabe zu konsumieren:
&e: ein positiver Lookahead (das heißt,emuss zwingend passen)!e: ein negativer Lookahead (das heißt,edarf zwingend nicht passen)
Die unären Operatoren (*, +, ?) binden so stark wie möglich; der senkrechte Strich (|) bindet am schwächsten.
Whitespace dient ausschließlich dazu, Tokens voneinander zu trennen.
Regeln stehen normalerweise in einer einzelnen Zeile, zu lange Regeln können jedoch umgebrochen werden:
literal: stringliteral | bytesliteral
| integer | floatnumber | imagnumber
Alternativ können Regeln so formatiert werden, dass die erste Zeile mit dem Doppelpunkt endet und jede Alternative mit einem senkrechten Strich in einer neuen Zeile beginnt. Zum Beispiel:
literal: | stringliteral | bytesliteral | integer | floatnumber | imagnumber
Dies bedeutet nicht, dass es eine leere erste Alternative gibt.
1.2.1. Lexikalische und syntaktische Definitionen¶
Es gibt einen Unterschied zwischen lexikalischer und syntaktischer Analyse: Der Lexikalische Analysierer arbeitet auf den einzelnen Zeichen der Eingabequelle, während der Parser (syntaktischer Analysierer) auf dem Datenstrom von Tokens arbeitet, die von der lexikalischen Analyse erzeugt wurden. In manchen Fällen ist die genaue Grenze zwischen den beiden Phasen jedoch ein CPython-Implementierungsdetail.
Der praktische Unterschied zwischen beiden besteht darin, dass in lexikalischen Definitionen sämtlicher Whitespace signifikant ist. Der lexikalische Analysierer verwirft allen Whitespace, der nicht in Tokens wie token.INDENT oder NEWLINE umgewandelt wird. Syntaktische Definitionen verwenden dann diese Tokens anstelle von Quelltext-Zeichen.
Diese Dokumentation verwendet dieselbe BNF-Grammatik für beide Arten von Definitionen. Alle Verwendungen von BNF im nächsten Kapitel (Lexical analysis) sind lexikalische Definitionen; Verwendungen in nachfolgenden Kapiteln sind syntaktische Definitionen.