Derzeit können in Python die Parameter und Rückgabetypen einer Funktion wie folgt angegeben werden:
def func(var1: str, var2: str) -> int:
return var1.index(var2)
Dies zeigt an, dass die Funktion zwei Zeichenfolgen akzeptiert und eine Ganzzahl zurückgibt.
Diese Syntax ist jedoch sehr verwirrend mit Lambdas, die wie folgt aussehen:
func = lambda var1, var2: var1.index(var2)
Ich habe versucht, Typhinweise sowohl für Parameter als auch für Rückgabetypen einzugeben, und ich kann keinen Weg finden, der keinen Syntaxfehler verursacht.
Ist es möglich, einen Hinweis auf eine Lambda-Funktion einzugeben? Wenn nicht, gibt es Pläne für Lambdas mit Typangaben oder einen Grund (neben dem offensichtlichen Syntaxkonflikt), warum nicht?
key
Argument für diesorted
integrierte Funktion verwendet werden können . Ich sehe wirklich keinen Sinn darin, Typhinweise in solch begrenzten Kontexten hinzuzufügen. Wenn Sie außerdem variable PEP-526-Anmerkungen verwenden, um Typhinweise hinzuzufügen,lambda
um den Punkt IMHO vollständig zu verfehlen. Dielambda
Syntax soll anonyme Funktionen definieren . Waslambda
bringt es, es zu verwenden und sofort an eine Variable zu binden? Einfach benutzendef
!Antworten:
Sie können in Python 3.6 und höher mithilfe von PEP 526-Variablenanmerkungen arbeiten . Sie können die Variable, der Sie das
lambda
Ergebnis zuweisen , mit demtyping.Callable
Generikum versehen :from typing import Callable func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
Dadurch werden die Typhinweisinformationen nicht an das Funktionsobjekt selbst angehängt, sondern nur an den Namespace, in dem Sie das Objekt gespeichert haben. Dies ist jedoch normalerweise alles, was Sie für Typhinweiszwecke benötigen.
Sie können jedoch auch einfach eine Funktionsanweisung verwenden. Der einzige Vorteil eines
lambda
Angebots besteht darin, dass Sie eine Funktionsdefinition für einen einfachen Ausdruck in einen größeren Ausdruck einfügen können. Das obige Lambda ist jedoch nicht Teil eines größeren Ausdrucks, sondern immer nur Teil einer Zuweisungsanweisung, die es an einen Namen bindet. Genau das würde einedef func(var1: str, var2: str): return var1.index(var2)
Aussage bewirken.Beachten Sie, dass Sie auch keine Anmerkungen
*args
oder**kwargs
Argumente separat erstellen können, wie in der Dokumentation für folgendeCallable
Zustände angegeben:Diese Einschränkung gilt nicht für ein PEP 544- Protokoll mit einer
__call__
Methode . Verwenden Sie diese Option, wenn Sie eine aussagekräftige Definition benötigen, welche Argumente akzeptiert werden sollen. Sie benötigen Python 3.8 oder installieren dastyping-extensions
Projekt für einen Backport:from typing-extensions import Protocol class SomeCallableConvention(Protocol): def __call__(var1: str, var2: str, spam: str = "ham") -> int: ... func: SomeCallableConvention = lambda var1, var2, spam="ham": var1.index(var2) * spam
Für den
lambda
Ausdruck selbst können Sie keine Anmerkungen verwenden (die Syntax, auf der Pythons Typhinweise basieren). Die Syntax ist nur fürdef
Funktionsanweisungen verfügbar .Aus PEP 3107 - Funktionsanmerkungen :
Sie können die Anmerkungen weiterhin direkt an das Objekt anhängen. Das
function.__annotations__
Attribut ist ein beschreibbares Wörterbuch:>>> def func(var1: str, var2: str) -> int: ... return var1.index(var2) ... >>> func.__annotations__ {'var1': <class 'str'>, 'return': <class 'int'>, 'var2': <class 'str'>} >>> lfunc = lambda var1, var2: var1.index(var2) >>> lfunc.__annotations__ {} >>> lfunc.__annotations__['var1'] = str >>> lfunc.__annotations__['var2'] = str >>> lfunc.__annotations__['return'] = int >>> lfunc.__annotations__ {'var1': <class 'str'>, 'return': <class 'int'>, 'var2': <class 'str'>}
Nicht, dass dynamische Annotationen wie diese Ihnen helfen würden, wenn Sie einen statischen Analysator über Ihre Typhinweise ausführen möchten.
quelle
func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
warum ist dann keine bessere Antwortdef func(var1: str, var2: str) -> int: return var1.index(var2)
???Seit Python 3.6 können Sie (siehe PEP 526 ):
from typing import Callable is_even: Callable[[int], bool] = lambda x: (x % 2 == 0)
quelle
x
?is_even
Funktion ist eineCallable
, die einint
Argument erwartet , also ist x eineint
.is_even('x')
Verursacht einen Tippfehler .Nein, es ist nicht möglich, es gibt keine Pläne, dies zu ändern, und die Gründe sind hauptsächlich syntaktisch.
quelle