python-3.x graficas - ¿Qué significa->en las definiciones de funciones de Python?




variables letras (4)

Recientemente he notado algo interesante al observar la especificación gramatical de Python 3.3 :

funcdef: 'def' NAME parameters ['->' test] ':' suite

El bloque de 'flecha' opcional estaba ausente en Python 2 y no pude encontrar ninguna información sobre su significado en Python 3. Resulta que es Python correcto y es aceptado por el intérprete:

def f(x) -> 123:
    return x

Pensé que esto podría ser una especie de sintaxis de condición previa, pero:

  • No puedo probar x aquí, todavía no está definido,
  • No importa lo que coloque después de la flecha (por ejemplo, 2 < 1 ), no afecta el comportamiento de la función.

¿Podría alguien acostumbrado con esta sintaxis explicarlo?


Answers

Como han indicado otras respuestas, el símbolo -> se utiliza como parte de las anotaciones de funciones. En versiones más recientes de Python >= 3.5 , sin embargo, tiene un significado definido .

PEP 3107 - Las anotaciones de funciones describieron la especificación, definieron los cambios gramaticales, la existencia de func.__annotations__ en las que están almacenados y el hecho de que su caso de uso aún está abierto.

Sin embargo, en Python 3.5 , PEP 484 - Sugerencias de tipo agrega un solo significado a esto: -> se utiliza para indicar el tipo que devuelve la función. También parece que esto se aplicará en futuras versiones como se describe en ¿Qué pasa con los usos existentes de las anotaciones ?

El esquema más rápido concebible introduciría la eliminación silenciosa de las anotaciones de sugerencia no de tipo en 3.6, la depreciación completa en 3.7, y declararía sugerencias de tipo como el único uso permitido de anotaciones en Python 3.8.

(Énfasis mío)

Por lo que puedo decir, esto no se ha implementado en la versión 3.6 por lo que podría llegar a versiones futuras.

De acuerdo con esto, el ejemplo que has suministrado:

def f(x) -> 123:
    return x

estará prohibido en el futuro (y en las versiones actuales será confuso), tendría que cambiarse a:

def f(x) -> int:
    return x

para que describa efectivamente esa función f devuelve un objeto de tipo int .

Las anotaciones no son utilizadas de ninguna manera por Python, ya que las rellena y las ignora. Depende de las bibliotecas de terceros trabajar con ellos.


Estas son anotaciones de funciones cubiertas en PEP 3107 . Específicamente, -> marca la anotación de la función de retorno.

Ejemplos:

>>> def kinetic_energy(m:'in KG', v:'in M/S')->'Joules': 
...    return 1/2*m*v**2
... 
>>> kinetic_energy.__annotations__
{'return': 'Joules', 'v': 'in M/S', 'm': 'in KG'}

Las anotaciones son diccionarios, así que puedes hacer esto:

>>> '{:,} {}'.format(kinetic_energy(20,3000),
      kinetic_energy.__annotations__['return'])
'90,000,000.0 Joules'

También puede tener una estructura de datos de Python en lugar de solo una cadena:

>>> rd={'type':float,'units':'Joules','docstring':'Given mass and velocity returns kinetic energy in Joules'}
>>> def f()->rd:
...    pass
>>> f.__annotations__['return']['type']
<class 'float'>
>>> f.__annotations__['return']['units']
'Joules'
>>> f.__annotations__['return']['docstring']
'Given mass and velocity returns kinetic energy in Joules'

O bien, puede usar atributos de función para validar los valores llamados:

def validate(func, locals):
    for var, test in func.__annotations__.items():
        value = locals[var]
        try: 
            pr=test.__name__+': '+test.__docstring__
        except AttributeError:
            pr=test.__name__   
        msg = '{}=={}; Test: {}'.format(var, value, pr)
        assert test(value), msg

def between(lo, hi):
    def _between(x):
            return lo <= x <= hi
    _between.__docstring__='must be between {} and {}'.format(lo,hi)       
    return _between

def f(x: between(3,10), y:lambda _y: isinstance(_y,int)):
    validate(f, locals())
    print(x,y)

Huellas dactilares

>>> f(2,2) 
AssertionError: x==2; Test: _between: must be between 3 and 10
>>> f(3,2.1)
AssertionError: y==2.1; Test: <lambda>

Es una anotación de función .

En más detalle, Python 2.x tiene cadenas de documentación, que le permiten adjuntar una cadena de metadatos a varios tipos de objetos. Esto es increíblemente práctico, por lo que Python 3 amplía la función al permitirle adjuntar metadatos a las funciones que describen sus parámetros y valores de retorno.

No hay un caso de uso preconcebido, pero el PEP sugiere varios. Una muy útil es permitirle anotar parámetros con sus tipos esperados; entonces sería fácil escribir un decorador que verifique las anotaciones o coaccione los argumentos al tipo correcto. Otra es permitir la documentación específica del parámetro en lugar de codificarla en la cadena de documentación.


Otra forma de averiguar si una cadena contiene algunos caracteres o no con el valor de retorno booleano (es decir, True o `Falso):

str1 = "This be a string"
find_this = "tr"
if find_this in str1:
    print find_this, " is been found in ", str1
else:
    print find_this, " is not found in ", str1




python python-3.x annotations function-definition