Actualmente, en Python, los parámetros de una función y los tipos de retorno se pueden insinuar de la siguiente manera:
def func(var1: str, var2: str) -> int:
return var1.index(var2)
Lo que indica que la función toma dos cadenas y devuelve un número entero.
Sin embargo, esta sintaxis es muy confusa con lambdas, que se ven así:
func = lambda var1, var2: var1.index(var2)
Intenté poner sugerencias de tipo tanto en parámetros como en tipos de retorno, y no puedo encontrar una forma que no cause un error de sintaxis.
¿Es posible escribir una sugerencia de una función lambda? Si no es así, ¿hay planes para aplicar lambdas de sugerencia de tipo, o por alguna razón (además del obvio conflicto de sintaxis) por qué no?
key
argumento de la funciónsorted
integrada. Realmente no veo ningún sentido en agregar sugerencias de tipo en contextos tan limitados. Además, el uso de anotaciones de variables PEP-526 para agregar sugerencias de tipo no entiende porlambda
completo, en mi humilde opinión. Lalambda
sintaxis está destinada a definir funciones anónimas . ¿Cuál es el punto de usarlambda
y vincularlo inmediatamente a una variable? ¡Solo usadef
!Respuestas:
Puede, en cierto modo, en Python 3.6 y versiones posteriores usando anotaciones de variables PEP 526 . Puede anotar la variable a la que asigna el
lambda
resultado con eltyping.Callable
genérico :from typing import Callable func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
Esto no adjunta la información de sugerencia de tipo al objeto de función en sí, solo al espacio de nombres en el que almacenó el objeto, pero esto suele ser todo lo que necesita para fines de sugerencia de tipo.
Sin embargo, también puede usar una declaración de función en su lugar; la única ventaja que
lambda
ofrece a es que puede poner una definición de función para una expresión simple dentro de una expresión más grande. Pero la lambda anterior no es parte de una expresión más grande, solo es parte de una declaración de asignación, vinculándola a un nombre. Eso es exactamente lodef func(var1: str, var2: str): return var1.index(var2)
que lograría una declaración.Tenga en cuenta que no se puede hacer anotaciones
*args
o**kwargs
argumentos por separado o bien, como la documentación deCallable
los estados:Esa limitación no se aplica a un protocolo PEP 544 con un método
__call__
; utilice esto si necesita una definición expresiva de qué argumentos deben aceptarse. Necesita Python 3.8 o instalar eltyping-extensions
proyecto para un 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
Para la
lambda
expresión en sí , no puede usar ninguna anotación (la sintaxis en la que se construye la sugerencia de tipo de Python). La sintaxis solo está disponible paradef
declaraciones de función.De PEP 3107 - Anotaciones de funciones :
Aún puede adjuntar las anotaciones directamente al objeto, el
function.__annotations__
atributo es un diccionario escribible:>>> 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'>}
No es que las anotaciones dinámicas como estas vayan a ayudarlo cuando desee ejecutar un analizador estático sobre sus sugerencias de tipo, por supuesto.
fuente
func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
, ¿por qué no hay una mejor respuestadef func(var1: str, var2: str) -> int: return var1.index(var2)
?Desde Python 3.6, puede (ver PEP 526 ):
from typing import Callable is_even: Callable[[int], bool] = lambda x: (x % 2 == 0)
fuente
x
?is_even
función es unaCallable
que espera unint
argumento, por lo que x es unaint
.is_even('x')
provoca un error de tipo.No, no es posible, no hay planes para cambiar esto, y las razones son principalmente sintácticas.
fuente