Actuellement, en Python, les paramètres et les types de retour d'une fonction peuvent être représentés comme suit:
def func(var1: str, var2: str) -> int:
return var1.index(var2)
Ce qui indique que la fonction prend deux chaînes et retourne un entier.
Cependant, cette syntaxe est très déroutante avec les lambdas, qui ressemblent à:
func = lambda var1, var2: var1.index(var2)
J'ai essayé de mettre des indices de type sur les paramètres et les types de retour, et je ne peux pas trouver un moyen qui ne provoque pas d'erreur de syntaxe.
Est-il possible de taper hint une fonction lambda? Si ce n'est pas le cas, existe-t-il des plans pour les lambdas de type hinting, ou pour une raison (en plus du conflit de syntaxe évident) pourquoi pas?
Vous pouvez, en quelque sorte, dans Python 3.6 et plus en utilisant annotations de variables PEP 526 . Vous pouvez annoter la variable à laquelle vous affectez le résultat lambda
avec avec les typing.Callable
générique :
from typing import Callable
func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
Cela n'attache pas les informations d'indication de type à l'objet fonction lui-même, uniquement à l'espace de noms dans lequel vous avez stocké l'objet, mais c'est généralement tout ce dont vous avez besoin à des fins d'indication de type. Notez que vous ne pouvez pas annoter *args
ou **kwargs
arguments séparément de cette façon, comme l'indique la documentation de Callable
:
Il n'y a pas de syntaxe pour indiquer des arguments facultatifs ou des mots clés; ces types de fonctions sont rarement utilisés comme types de rappel.
Pour l'expression lambda
elle-même , vous ne pouvez pas utiliser d'annotations (la syntaxe sur laquelle l'indication de type de Python est construite). La syntaxe n'est disponible que pour les instructions de fonction def
.
De PEP 3107 - Annotations de fonction :
la syntaxe de lambda ne prend pas en charge les annotations. La syntaxe de lambda pourrait être modifiée pour prendre en charge les annotations, en exigeant des parenthèses autour de la liste des paramètres. Cependant il a été décidé de ne pas faire ce changement car:
- Ce serait un changement incompatible.
- Les Lambda sont stérilisées de toute façon.
- Le lambda peut toujours être changé en fonction.
Vous pouvez toujours attacher les annotations directement à l'objet, le function.__annotations__
l'attribut est un dictionnaire accessible en écriture:
>>> 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'>}
Ce n'est pas que des annotations dynamiques comme celles-ci vont vous aider, bien sûr, lorsque vous vouliez exécuter un analyseur statique sur vos indices de type.
Depuis Python 3.6, vous pouvez (voir PEP 526 ):
from typing import Callable
is_even: Callable[[int], bool] = lambda x: (x % 2 == 0)
Comme l'a noté l'utilisateur c-z, ce n'est pas la même chose que d'annoter la signature d'une fonction non anonyme. Mypy v0.620 ne se plaint pas si vous passez une variable str
à is_even
dans l'exemple ci-dessus.