PEP 3117 – Postfix-Typdeklarationen
- Autor:
- Georg Brandl <georg at python.org>
- Status:
- Abgelehnt
- Typ:
- Standards Track
- Erstellt:
- 01-Apr-2007
- Python-Version:
- 3.0
- Post-History:
Zusammenfassung
Diese PEP schlägt die Hinzufügung einer Postfix-Syntax für Typdeklarationen zu Python vor. Sie spezifiziert auch eine neue typedef-Anweisung, die zum Erstellen neuer Zuordnungen zwischen Typen und Deklaratoren verwendet wird.
Ihre Annahme wird das Benutzererlebnis von Python erheblich verbessern und eine der Macken beseitigen, die Benutzer anderer Programmiersprachen davon abhalten, zu Python zu wechseln.
Begründung
Python leidet seit langem unter dem Mangel an expliziten Typdeklarationen. Als einer der wenigen Aspekte, in denen sich die Sprache von ihrem Zen unterscheidet, hat diese Macke viele Diskussionen zwischen Python-Häretikern und Mitgliedern der PSU (einige Beispiele siehe [EX1], [EX2] oder [EX3]) ausgelöst und auch einen groß angelegten Unternehmenserfolg unwahrscheinlich gemacht.
Wenn man jedoch diesem Elend ein Ende setzen will, muss eine anständige Python-Syntax gefunden werden. In fast allen Sprachen, die sie haben, fehlt es Typdeklarationen an dieser Qualität: Sie sind umständlich, erfordern oft *mehrere Wörter* für einen einzigen Typ, oder sie sind schwer zu verstehen (z.B. verwendet eine bestimmte Sprache völlig unrelated [1] Adjektive wie dim für die Typdeklaration).
Daher kombiniert diese PEP den Schritt zu Typdeklarationen mit einem weiteren kühnen Schritt, der erneut beweist, dass Python nicht nur zukunftssicher, sondern auch zukunftsfreundlich ist: die Einführung von Unicode-Zeichen als integralen Bestandteil des Quellcodes.
Unicode ermöglicht es, mit viel weniger Zeichen viel mehr auszudrücken, was mit dem Zen („Lesbarkeit zählt.“) übereinstimmt. Außerdem entfällt die Notwendigkeit einer separaten Typdeklarationsanweisung, und nicht zuletzt zieht Python damit mit Perl 6 gleich, das bereits Unicode für seine Operatoren verwendet. [2]
Spezifikation
Wenn der Typdeklarationsmodus in Betrieb ist, wird die Grammatik so geändert, dass jedes NAME aus zwei Teilen bestehen muss: einem Namen und einem Typdeklarator, der genau ein Unicode-Zeichen ist.
Der Deklarator gibt eindeutig den Typ des Namens an, und wenn er auf der linken Seite eines Ausdrucks vorkommt, wird dieser Typ erzwungen: Eine InquisitionError-Ausnahme wird ausgelöst, wenn der zurückgegebene Typ nicht mit dem deklarierten Typ übereinstimmt. [3]
Auch die Ergebnistypen von Funktionsaufrufen müssen angegeben werden. Wenn das Ergebnis des Aufrufs nicht den deklarierten Typ hat, wird eine InquisitionError ausgelöst. Vorsicht: Der Deklarator für das Ergebnis sollte nicht mit dem Deklarator für das Funktionsobjekt verwechselt werden (siehe Beispiel unten).
Typdeklaratoren nach Namen, die nur gelesen und nicht zugewiesen werden, sind nicht unbedingt erforderlich, werden aber trotzdem erzwungen (siehe Python Zen: „Explizit ist besser als implizit.“).
Die Zuordnung zwischen Typen und Deklaratoren ist nicht statisch. Sie kann vom Programmierer vollständig angepasst werden, aber zur Bequemlichkeit gibt es einige vordefinierte Zuordnungen für einige integrierte Typen
| Typ | Deklarator |
|---|---|
object |
� (ERSETZUNGSZEICHEN) |
int |
ℕ (DOPPELT GESTRICHENE GROSSBUCHSTABE N) |
float |
℮ (GESCHÄTZTES SYMBOL) |
bool |
✓ (HÄKCHEN) |
complex |
ℂ (DOPPELT GESTRICHENE GROSSBUCHSTABE C) |
str |
✎ (LOWER RIGHT PENCIL) |
unicode |
✒ (BLACK NIB) |
tuple |
⒯ (Klammeraffe LATIN KLEINBUCHSTABE T) |
list |
♨ (HEISSE QUELLEN) |
dict |
⧟ (DOPPELSEITIGER MULTIMAP) |
set |
∅ (LEERE MENGE) (Hinweis: dies gilt auch für vollständige Mengen) |
frozenset |
☃ (SCHNEEMANN) |
datetime |
⌚ (UHR) |
function |
ƛ (LATEINISCHER KLEINBUCHSTABE LAMBDA MIT SCHRÄGSTRICH) |
generator |
⚛ (ATOM-SYMBOL) |
Exception |
⌁ (ELEKTRISCHER PFEIL) |
Der Deklarator für den None-Typ ist ein Nullbreitenleerzeichen.
Diese Zeichen sollten für jeden Programmierer offensichtlich, leicht zu merken und einzugeben sein.
Unicode-Ersatzeinheiten
Da selbst in unserer modernen, globalisierten Welt noch einige altmodische Rebellen gibt, die Unicode nicht in ihrem Quellcode verwenden können oder wollen, und da Python eine nachsichtige Sprache ist, wird für diese eine Fallback-Lösung bereitgestellt
Anstelle des einzelnen Unicode-Zeichens können sie name${UNICODE NAME DES DEKLARATORS}$ eingeben. Zum Beispiel sind diese beiden Funktionsdefinitionen äquivalent
def fooƛ(xℂ):
return None
und
def foo${LATIN SMALL LETTER LAMBDA WITH STROKE}$(x${DOUBLE-STRUCK CAPITAL C}$):
return None${ZERO WIDTH NO-BREAK SPACE}$
Das ist immer noch gut lesbar und macht die volle Leistung des Typ-annotierten Pythons für ASCII-Gläubige verfügbar.
Die typedef-Anweisung
Die Zuordnung zwischen Typen und Deklaratoren kann mit dieser neuen Anweisung erweitert werden.
Die Syntax lautet wie folgt
typedef_stmt ::= "typedef" expr DECLARATOR
wobei expr zu einem Typobjekt aufgelöst wird. Zur Bequemlichkeit kann die typedef-Anweisung auch mit der class-Anweisung für neue Klassen gemischt werden, wie hier
typedef class Foo☺(object�):
pass
Beispiel
Dies ist die Standardfunktion os.path.normpath, konvertiert in Typdeklarationssyntax
def normpathƛ(path✎)✎:
"""Normalize path, eliminating double slashes, etc."""
if path✎ == '':
return '.'
initial_slashes✓ = path✎.startswithƛ('/')✓
# POSIX allows one or two initial slashes, but treats three or more
# as single slash.
if (initial_slashes✓ and
path✎.startswithƛ('//')✓ and not path✎.startswithƛ('///')✓)✓:
initial_slashesℕ = 2
comps♨ = path✎.splitƛ('/')♨
new_comps♨ = []♨
for comp✎ in comps♨:
if comp✎ in ('', '.')⒯:
continue
if (comp✎ != '..' or (not initial_slashesℕ and not new_comps♨)✓ or
(new_comps♨ and new_comps♨[-1]✎ == '..')✓)✓:
new_comps♨.appendƛ(comp✎)
elif new_comps♨:
new_comps♨.popƛ()✎
comps♨ = new_comps♨
path✎ = '/'.join(comps♨)✎
if initial_slashesℕ:
path✎ = '/'*initial_slashesℕ + path✎
return path✎ or '.'
Wie Sie deutlich sehen können, verleihen die Typdeklarationen Ausdrucksstärke und lassen den Code gleichzeitig viel professioneller aussehen.
Kompatibilitätsprobleme
Um den Typdeklarationsmodus zu aktivieren, muss man schreiben
from __future__ import type_declarations
was die Unicode-Analyse der Quelle aktiviert [4], macht typedef zu einem Schlüsselwort und erzwingt korrekte Typen für alle Zuweisungen und Funktionsaufrufe.
Ablehnung
Nach sorgfältiger Überlegung, viel Selbstreflexion, Zähneknirschen und Zerreißen von Gewändern wurde beschlossen, diese PEP abzulehnen.
Referenzen
Danksagungen
Vielen Dank an Armin Ronacher, Alexander Schremmer und Marek Kubica, die geholfen haben, die am besten geeigneten und einprägsamsten Deklaratoren für integrierte Typen zu finden.
Vielen Dank auch an das Unicode-Konsortium für die Aufnahme all dieser nützlichen Zeichen in den Unicode-Standard.
Urheberrecht
Dieses Dokument wurde gemeinfrei erklärt.
Quelle: https://github.com/python/peps/blob/main/peps/pep-3117.rst
Zuletzt geändert: 2025-02-01 08:59:27 GMT