Funktionsanmerkungen: PEP-3107
Ich bin auf einen Codeausschnitt gestoßen, der die Funktionsanmerkungen von Python3 demonstriert. Das Konzept ist einfach, aber ich kann mir nicht vorstellen, warum diese in Python3 implementiert wurden oder für welche Zwecke sie gut geeignet sind. Vielleicht kann mich SO aufklären?
Wie es funktioniert:
def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
... function body ...
Alles, was nach einem Argument auf den Doppelpunkt folgt, ist eine 'Annotation', und die darauf folgenden Informationen ->
sind eine Annotation für den Rückgabewert der Funktion.
foo.func_annotations würde ein Wörterbuch zurückgeben:
{'a': 'x',
'b': 11,
'c': list,
'return': 9}
Welche Bedeutung hat es, dies zur Verfügung zu haben?
python
function
annotations
python-3.x
Agscala
quelle
quelle
foo.func_annotations
seinfoo.__annotations__
in python3?def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
bedeuten?Antworten:
Ich finde das eigentlich toll.
Ich komme aus dem akademischen Bereich und kann Ihnen sagen, dass sich Anmerkungen als von unschätzbarem Wert erwiesen haben, um intelligente statische Analysegeräte für Sprachen wie Java zu ermöglichen. Sie können beispielsweise Semantiken wie Statusbeschränkungen, Threads, auf die zugegriffen werden darf, Architekturbeschränkungen usw. definieren, und es gibt eine ganze Reihe von Tools, die diese dann lesen und verarbeiten können, um Sicherheiten zu bieten, die über das hinausgehen, was Sie von den Compilern erhalten. Sie könnten sogar Dinge schreiben, die Vor- / Nachbedingungen überprüfen.
Ich bin der Meinung, dass so etwas in Python wegen seiner schwächeren Typisierung besonders benötigt wird, aber es gab wirklich keine Konstrukte, die dies einfach und Teil der offiziellen Syntax machten.
Es gibt andere Verwendungszwecke für Anmerkungen, die nicht sicher sind. Ich kann sehen, wie ich meine Java-basierten Tools auf Python anwenden kann. Zum Beispiel habe ich ein Tool, mit dem Sie Methoden spezielle Warnungen zuweisen können und das Ihnen beim Aufrufen Hinweise gibt, dass Sie deren Dokumentation lesen sollten (Stellen Sie sich beispielsweise vor, Sie haben eine Methode, die nicht mit einem negativen Wert aufgerufen werden darf, aber es ist nicht intuitiv aus dem Namen). Mit Anmerkungen könnte ich technisch so etwas für Python schreiben. Ebenso kann ein Tool geschrieben werden, das Methoden in einer großen Klasse basierend auf Tags organisiert, wenn eine offizielle Syntax vorhanden ist.
quelle
Funktionsanmerkungen sind das, was Sie daraus machen.
Sie können zur Dokumentation verwendet werden:
Sie können zur Überprüfung der Vorbedingungen verwendet werden:
Unter http://www.python.org/dev/peps/pep-0362/ finden Sie auch eine Möglichkeit, die Typprüfung zu implementieren.
quelle
Mass
undVelocity
stattdessen.def kinetic_energy(mass: 'in kilograms', velocity: 'in meters per second') -> float:
auch den Rückgabetyp anzeigen. Dies ist meine Lieblingsantwort hier.return
Anmerkung mithilfe Ihres Codes zu überprüfen ? Es scheint nicht inlocals
Dies ist eine sehr späte Antwort, aber AFAICT, die derzeit beste Verwendung von Funktionsanmerkungen, ist PEP-0484 und MyPy .
So verwendet:
quelle
list(fib('a'))
mit Ihrer Beispielfunktion tippe, akzeptiert Python 3.7 das Argument gerne und beschwert sich darüber, dass es keine Möglichkeit gibt, einen String und einen Int zu vergleichen.Um ein konkretes Beispiel für eine gute Verwendung aus meiner Antwort hier hinzuzufügen , kann in Verbindung mit Dekorateuren ein einfacher Mechanismus für Multimethoden durchgeführt werden.
und ein Anwendungsbeispiel:
Dies kann durch Hinzufügen der Typen zum Dekorateur erfolgen, wie Guidos ursprünglicher Beitrag zeigt. Das Kommentieren der Parameter selbst ist jedoch besser, da die Möglichkeit einer falschen Übereinstimmung von Parametern und Typen vermieden wird.
Hinweis : In Python können Sie auf die Anmerkungen zugreifen,
function.__annotations__
anstattfunction.func_annotations
denfunc_*
Stil in Python 3 zu entfernen.quelle
function = self.typemap.get(types)
dass sie nicht funktioniert, wenn Unterklassen beteiligt sind. In diesem Fall müssten Sie wahrscheinlich dietypemap
Verwendung durchlaufenisinnstance
. Ich frage mich, ob@overload
das richtig__annotations__
ist einedict
, die die Reihenfolge der Argumente nicht sicherstellt, daher schlägt dieses Snippet manchmal fehl. Ich würde empfehlen, dastypes = tuple(...)
aufspec = inspect.getfullargspec(function)
dann zu änderntypes = tuple([spec.annotations[x] for x in spec.args])
.Uri hat bereits eine richtige Antwort gegeben, daher hier eine weniger ernste: So können Sie Ihre Docstrings kürzer machen.
quelle
Als ich das erste Mal Anmerkungen sah, fand ich "großartig! Endlich kann ich mich für eine Typprüfung entscheiden!" Natürlich hatte ich nicht bemerkt, dass Anmerkungen nicht wirklich erzwungen werden.
Also habe ich beschlossen , einen einfachen Funktionsdekorateur zu schreiben, um sie durchzusetzen :
Ich habe es der Ensure- Bibliothek hinzugefügt .
quelle
Es ist lange her, dass dies gestellt wurde, aber das in der Frage angegebene Beispiel-Snippet stammt (wie auch dort angegeben) aus PEP 3107, und am Ende dieses PEP-Beispiels werden auch Anwendungsfälle angegeben, die die Frage aus PEPs-Sicht von beantworten könnten Aussicht ;)
Das Folgende wird aus PEP3107 zitiert
Anwendungsfälle
Im Verlauf der Erörterung von Anmerkungen wurde eine Reihe von Anwendungsfällen angesprochen. Einige davon werden hier vorgestellt, gruppiert nach der Art der Informationen, die sie vermitteln. Ebenfalls enthalten sind Beispiele für vorhandene Produkte und Pakete, die Anmerkungen verwenden könnten.
Weitere Informationen zu bestimmten Punkten (sowie deren Referenzen) finden Sie im PEP.
quelle
Python 3.X (nur) verallgemeinert auch die Funktionsdefinition, damit Argumente und Rückgabewerte mit Objektwerten zur Verwendung in Erweiterungen kommentiert werden können .
Seine META-Daten zu erklären, um die Funktionswerte genauer zu beschreiben.
Anmerkungen werden wie
:value
nach dem Argumentnamen und vor einem Standard sowie->value
nach der Argumentliste codiert .Sie werden in einem
__annotations__
Attribut der Funktion gesammelt , aber von Python selbst nicht als besonders behandelt:BEISPIEL:
Das
typeannotations
Modul bietet eine Reihe von Tools zur Typprüfung und Typinferenz von Python-Code. Es enthält auch eine Reihe von Typen, die zum Kommentieren von Funktionen und Objekten nützlich sind.Diese Tools sind hauptsächlich für statische Analysegeräte wie Linters, Code-Vervollständigungsbibliotheken und IDEs konzipiert. Zusätzlich werden Dekorateure zur Durchführung von Laufzeitprüfungen bereitgestellt. Die Überprüfung des Laufzeit-Typs ist in Python nicht immer eine gute Idee, kann jedoch in einigen Fällen sehr nützlich sein.
https://github.com/ceronman/typeannotations
Wie das Schreiben hilft, besseren Code zu schreiben
PEP 526 - Syntax für variable Anmerkungen
https://www.python.org/dev/peps/pep-0526/
https://www.attrs.org/en/stable/types.html
quelle
Trotz aller hier beschriebenen Verwendungen wird die durchsetzbare und höchstwahrscheinlich erzwungene Verwendung von Anmerkungen für Typhinweise verwendet .
Dies wird derzeit in keiner Weise erzwungen, aber nach PEP 484 lassen zukünftige Versionen von Python nur Typen als Wert für Anmerkungen zu.
Zitieren Was ist mit vorhandenen Verwendungen von Anmerkungen? ::
Obwohl ich in 3.6 noch keine stillen Abwertungen gesehen habe, könnte dies stattdessen auf 3.7 erhöht werden.
Auch wenn es einige andere gute Anwendungsfälle gibt, ist es am besten, sie nur als Typhinweise zu verwenden, wenn Sie in Zukunft nicht alles ändern möchten, wo diese Einschränkung besteht.
quelle
Als etwas verzögerte Antwort verwenden einige meiner Pakete (marrow.script, WebCore usw.), sofern verfügbar, Anmerkungen, um die Typumwandlung zu deklarieren (dh eingehende Werte aus dem Web zu transformieren, zu erkennen, welche Argumente boolesche Schalter sind usw.) um ein zusätzliches Markup von Argumenten durchzuführen.
Marrow Script erstellt eine vollständige Befehlszeilenschnittstelle für beliebige Funktionen und Klassen und ermöglicht das Definieren von Dokumentations-, Casting- und Rückruf-abgeleiteten Standardwerten über Anmerkungen mit einem Dekorator, der ältere Laufzeiten unterstützt. Alle meine Bibliotheken, die Anmerkungen verwenden, unterstützen die Formulare:
Die "Bare" -Unterstützung für Docstrings oder Typecasting-Funktionen ermöglicht ein einfacheres Mischen mit anderen Bibliotheken, die Anmerkungen berücksichtigen. (Dh ich habe einen Web-Controller, der Typecasting verwendet und zufällig auch als Befehlszeilenskript verfügbar gemacht wird.)
Bearbeitet, um hinzuzufügen: Ich habe auch damit begonnen, das TypeGuard- Paket mithilfe von Zusicherungen zur Entwicklungszeit zur Validierung zu verwenden. Vorteil: Bei Ausführung mit aktivierten "Optimierungen" (
-O
/PYTHONOPTIMIZE
env var) werden die möglicherweise teuren (z. B. rekursiven) Überprüfungen weggelassen, mit der Idee, dass Sie Ihre App in der Entwicklung ordnungsgemäß getestet haben, sodass die Überprüfungen in der Produktion unnötig sein sollten.quelle
Anmerkungen können zum einfachen Modularisieren von Code verwendet werden. Zum Beispiel könnte ein Modul für ein Programm, das ich pflege, einfach eine Methode definieren wie:
und wir könnten den Benutzer nach einem Ding namens "param1" fragen, das "zum Zählen benötigt" ist und ein "int" sein sollte. Am Ende können wir sogar die vom Benutzer angegebene Zeichenfolge in den gewünschten Typ konvertieren, um die problemloseste Erfahrung zu erzielen.
In unserem Funktionsmetadatenobjekt finden Sie eine Open Source-Klasse, die dabei hilft und die benötigten Werte automatisch abrufen und in einen beliebigen Typ konvertieren kann (da die Annotation eine Konvertierungsmethode ist). Sogar IDEs zeigen Autocompletions richtig und gehen davon aus, dass die Typen den Anmerkungen entsprechen - eine perfekte Anpassung.
quelle
Wenn Sie sich die Liste der Vorteile von Cython ansehen, ist die Fähigkeit, dem Compiler mitzuteilen, welcher Typ ein Python-Objekt ist, eine wichtige.
Ich kann mir eine Zukunft vorstellen, in der Cython (oder ähnliche Tools, die einen Teil Ihres Python-Codes kompilieren) die Annotationssyntax verwenden wird, um ihre Magie zu entfalten.
quelle
multiply
Funktion zu zwingen , nur gegen ganze Zahlen zu arbeiten, wenn dies'na' * 8 + ' batman!'
vollständig gültig ist? ;)