PEP 457 – Notation für Positions-Only-Parameter
- Autor:
- Larry Hastings <larry at hastings.org>
- Discussions-To:
- Python-Dev Liste
- Status:
- Final
- Typ:
- Informational
- Erstellt:
- 08. Okt. 2013
Inhaltsverzeichnis
Übersicht
Diese PEP schlägt eine Notation für Positions-Only-Parameter in Python vor. Positions-Only-Parameter sind Parameter ohne einen extern nutzbaren Namen; wenn eine Funktion, die Positions-Only-Parameter akzeptiert, aufgerufen wird, werden Positionsargumente basierend auf ihrer Position diesen Parametern zugeordnet.
Diese PEP ist eine Informations-PEP, die die Notation beschreibt, die bei der Beschreibung von APIs verwendet werden soll, die Positions-Only-Parameter verwenden (z. B. in Argument Clinic oder in der Zeichenkettendarstellung von inspect.Signature-Objekten). Eine separate PEP, PEP 570, schlägt die Anhebung dieser Notation zu einer vollständigen Python-Syntax vor.
Begründung
Python unterstützt schon immer Positions-Only-Parameter. Frühe Versionen von Python kannten nicht das Konzept, Parameter nach Namen anzugeben, daher waren natürlich alle Parameter Positions-Only. Dies änderte sich um Python 1.0 herum, als alle Parameter plötzlich Positions-oder-Schlüsselwort wurden. Aber selbst in aktuellen Versionen von Python akzeptieren viele CPython „eingebaute“ Funktionen immer noch nur Positions-Only-Argumente.
In modernem Python implementierte Funktionen können eine beliebige Anzahl von Positions-Only-Argumenten über den variadischen *args-Parameter akzeptieren. Es gibt jedoch keine Python-Syntax, um die Akzeptanz einer bestimmten Anzahl von Positions-Only-Parametern anzugeben. Anders ausgedrückt, es gibt viele eingebaute Funktionen, deren Signaturen mit der Python-Syntax einfach nicht ausgedrückt werden können.
Diese PEP schlägt eine Notation für solche Signaturen vor, die die Grundlage für eine abwärtskompatible Syntax bilden könnte und die Implementierung jedes Built-ins in reinem Python-Code ermöglichen sollte (siehe PEP 570 für diesen Vorschlag).
Semantik von Positions-Only-Parametern im aktuellen Python
Es gibt viele, viele Beispiele für Built-ins, die nur Positions-Only-Parameter akzeptieren. Die daraus resultierende Semantik ist für den Python-Programmierer leicht erfahrbar – versuchen Sie einfach, eine davon aufzurufen und geben Sie ihre Argumente nach Namen an
>>> pow(x=5, y=3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pow() takes no keyword arguments
Darüber hinaus gibt es einige Funktionen mit besonders interessanter Semantik
range(), die einen optionalen Parameter links von ihrem erforderlichen Parameter akzeptiert. [2]dict(), dessen Mapping/Iterator-Parameter optional und semantisch Positions-Only sein muss. Jeder extern sichtbare Name für diesen Parameter würde diesen Namen verdecken, der in das**kwarg-Schlüsselwort-Variadic-Parameter-Dict eingeht! [1]
Offensichtlich kann man jeden dieser Fälle in reinem Python-Code simulieren, indem man (*args, **kwargs) akzeptiert und die Argumente von Hand parst. Dies führt jedoch zu einer Diskrepanz zwischen der Signatur der Python-Funktion und dem, was sie tatsächlich akzeptiert, ganz zu schweigen von der Arbeit, die für die Implementierung des genannten Argument-Parsings erforderlich ist.
Motivation
Diese PEP schlägt nicht vor, Positions-Only-Parameter in Python zu implementieren. Das Ziel dieser PEP ist es lediglich, die Syntax zu definieren, so dass
- Dokumentation klar, unzweideutig und konsistent genau ausdrücken kann, wie die Argumente einer Funktion interpretiert werden.
- Die Syntax wird für die zukünftige Verwendung reserviert, falls die Community eines Tages beschließt, Positions-Only-Parameter in die Sprache aufzunehmen.
- Argument Clinic kann eine Variante der Syntax als Teil seiner Eingabe verwenden, wenn Argumente für eingebaute Funktionen definiert werden.
Der aktuelle Stand der Dokumentation für Positions-Only-Parameter
Die Dokumentation für Positions-Only-Parameter ist unvollständig und inkonsistent
- Einige Funktionen bezeichnen optionale *Gruppen* von Positions-Only-Argumenten, indem sie diese in verschachtelte eckige Klammern einschließen. [3]
- Einige Funktionen bezeichnen optionale Gruppen von Positions-Only-Argumenten, indem sie mehrere Prototypen mit unterschiedlicher Anzahl von Argumenten präsentieren. [4]
- Einige Funktionen verwenden *beide* der oben genannten Ansätze. [2] [5]
Eine weitere wichtige zu berücksichtigende Idee: Derzeit gibt es in der Dokumentation keine Möglichkeit zu erkennen, ob eine Funktion Positions-Only-Parameter akzeptiert. open() akzeptiert Schlüsselwortargumente, ord() tut dies nicht, aber es gibt keine Möglichkeit, dies nur durch Lesen der Dokumentation zu erkennen.
Syntax und Semantik
Aus der „Zehntausend-Fuß-Sicht“, und vorerst unter Auslassung von *args und **kwargs, sieht die Grammatik für eine Funktionsdefinition derzeit so aus
def name(positional_or_keyword_parameters, *, keyword_only_parameters):
Aufbauend auf dieser Perspektive würde die neue Syntax für Funktionen so aussehen
def name(positional_only_parameters, /, positional_or_keyword_parameters,
*, keyword_only_parameters):
Alle Parameter vor dem / sind Positions-Only. Wenn / in einer Funktionssignatur nicht angegeben ist, akzeptiert diese Funktion keine Positions-Only-Parameter.
Positions-Only-Parameter können einen Standardwert haben und sind dann optional. Positions-Only-Parameter, die keinen Standardwert haben, sind „erforderliche“ Positions-Only-Parameter.
Weitere Semantik von Positions-Only-Parametern
- Obwohl Positions-Only-Parameter technisch gesehen Namen haben, sind diese Namen nur intern; Positions-Only-Parameter sind *niemals* extern namentlich ansprechbar. (Ähnlich wie bei
*argsund**kwargs.) - Wenn nach dem
/Argumente stehen, müssen Sie nach dem/ein Komma setzen, genau wie nach dem*, das den Übergang zu Schlüsselwort-Only-Parametern kennzeichnet. - Diese Syntax hat keine Auswirkungen auf
*argsoder**kwargs.
Zusätzliche Einschränkungen
Argument Clinic verwendet eine Form dieser Syntax zur Angabe von Built-ins. Sie legt weitere Einschränkungen auf, die theoretisch unnötig sind, aber die Implementierung erleichtern. Insbesondere
- Eine Funktion mit Positions-Only-Parametern kann derzeit keine andere Art von Parametern haben. (Dies wird wahrscheinlich in naher Zukunft leicht gelockert.)
- Argument Clinic unterstützt eine zusätzliche Syntax namens „optionale Gruppen“. Eine „optionale Gruppe“ ist eine sequentielle Menge von Positions-Only-Parametern, die als Gruppe angegeben oder nicht angegeben werden müssen. Wenn Sie beispielsweise eine Funktion in Argument Clinic definieren, die vier Parameter annimmt, und alle davon Positions-Only und in einer optionalen Gruppe sind, dann müssen Sie beim Aufruf der Funktion entweder null Argumente oder vier Argumente angeben. Dies ist notwendig, um mehr von Pythons Legacy-Bibliothek abzudecken, liegt jedoch außerhalb des Rahmens dieser PEP und wird für die tatsächliche Aufnahme in die Python-Sprache nicht empfohlen.
Hinweise für zukünftige Implementierer
Wenn wir uns entscheiden, Positions-Only-Parameter in einer zukünftigen Version von Python zu implementieren, müssten wir zusätzliche Arbeit leisten, um ihre Semantik zu erhalten. Das Problem: Wie informieren wir einen Parameter darüber, dass für ihn kein Wert übergeben wurde, als die Funktion aufgerufen wurde?
Die offensichtliche Lösung: Fügen Sie Python eine neue Singleton-Konstante hinzu, die übergeben wird, wenn ein Parameter keinem Argument zugeordnet wird. Ich schlage vor, dass der Wert undefined genannt wird und ein Singleton einer speziellen Klasse namens Undefined ist. Wenn ein Positions-Only-Parameter beim Aufruf kein Argument erhalten hat, wird sein Wert auf undefined gesetzt.
Aber das wirft ein weiteres Problem auf. Wie können wir unterscheiden zwischen „dieser Positions-Only-Parameter hat kein Argument erhalten“ und „der Aufrufer hat undefined für diesen Parameter übergeben“?
Es wäre schön, wenn es illegal wäre, undefined als Argument an eine Funktion zu übergeben – um beispielsweise eine Ausnahme auszulösen. Aber das würde Python verlangsamen, und die Regel „einvernehmliche Erwachsene“ scheint hier anwendbar zu sein. Daher sollte die Illegalität wahrscheinlich stark entmutigt, aber nicht gänzlich verhindert werden.
Es sollte jedoch zulässig sein (und gefördert werden), dass Benutzerfunktionen undefined als Standardwert für Parameter angeben.
Ungelöste Fragen
Es gibt drei Arten von Parametern in Python
- Positions-Only-Parameter,
- Positions-oder-Schlüsselwort-Parameter und
- Schlüsselwort-Only-Parameter.
Python erlaubt Funktionen, sowohl 2 als auch 3 zu haben. Und einige Built-ins (z. B. range) haben sowohl 1 als auch 3. Macht es Sinn, Funktionen zu haben, die sowohl 1 als auch 2 haben? Oder alle oben genannten?
Danksagungen
Die Gutschrift für die Verwendung von „/“ als Trennzeichen zwischen Positions-Only- und Positions-oder-Schlüsselwort-Parametern geht an Guido van Rossum, in einem Vorschlag von 2012. [6]
Die Gutschrift für die Priorisierung von linken optionalen Gruppen geht an Alyssa Coghlan. (Gespräch persönlich auf der PyCon US 2013.)
Urheberrecht
Dieses Dokument wurde gemeinfrei erklärt.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0457.rst
Zuletzt geändert: 2025-02-01 08:59:27 GMT