Terminología básica
PEP: PEP significa Propuesta de mejora de Python. Es un documento de diseño que describe nuevas funciones para Python o sus procesos o entorno. También proporciona información a la comunidad de python.
PEP es un mecanismo principal para proponer nuevas características importantes, por ejemplo, la interfaz de puerta de enlace del servidor web de Python, que recopila los aportes de la comunidad sobre los problemas y documenta las decisiones de diseño que se han implementado en Python.
Anotaciones de funciones: PEP 3107: PEP-3107 introdujo el concepto y la sintaxis para agregar anotaciones de metadatos arbitrarias a Python. Se introdujo en Python3, que anteriormente se hacía usando bibliotecas externas en python 2.x
¿Qué son las anotaciones de función?
Las anotaciones de funciones son expresiones arbitrarias de Python que están asociadas con varias partes de las funciones. Estas expresiones se evalúan en tiempo de compilación y no tienen vida en el entorno de tiempo de ejecución de python. Python no atribuye ningún significado a estas anotaciones. Toman vida cuando son interpretados por bibliotecas de terceros, por ejemplo, mypy.
Propósito de las anotaciones de funciones:
los beneficios de las anotaciones de funciones solo se pueden obtener a través de bibliotecas de terceros. El tipo de beneficios depende del tipo de biblioteca, por ejemplo
- Python admite escritura dinámica y, por lo tanto, no se proporciona ningún módulo para la verificación de tipos. Anotaciones como
[def foo(a:”int”, b:”float”=5.0) -> ”int”]
(sintaxis descrita en detalle en la siguiente sección) se puede utilizar para recopilar información sobre el tipo de los parámetros y el tipo de retorno de la función para realizar un seguimiento del cambio de tipo que se produce en la función. ‘mypy’ es una de esas bibliotecas.
- Las bibliotecas pueden utilizar anotaciones basadas en strings para proporcionar mejores mensajes de ayuda en tiempo de compilación con respecto a las funcionalidades de varios métodos, clases y módulos.
Sintaxis de las anotaciones de funciones
Son como los parámetros opcionales que siguen al nombre del parámetro.
- Nota: La palabra ‘expresión’ que se menciona a continuación puede ser el tipo de los parámetros que se deben pasar o comentar o cualquier string arbitraria que las bibliotecas externas puedan usar de manera significativa.
- Anotaciones para parámetros simples: el nombre del argumento va seguido de ‘:’, que luego va seguido de la expresión. La sintaxis de las anotaciones se muestra a continuación.
def foobar(a: expression, b: expression = 5):
- Anotaciones para parámetros en exceso: los parámetros en exceso, por ejemplo, *args y **kwargs, permiten pasar un número arbitrario de argumentos en una llamada de función. La sintaxis de anotación de dichos parámetros se muestra a continuación.
def foobar(*args: expression, *kwargs: expression):
- Anotaciones para parámetros anidados: los parámetros anidados son una característica útil de python 2x donde se pasa una tupla en una llamada de función y se lleva a cabo el desempaquetado automático. Esta función se elimina en python 3x y se debe realizar un desempaquetado manual. La anotación se realiza después de la variable y no después de la tupla, como se muestra a continuación.
def foobar((a: expression, b: expression), (c: expression, d: expression)):
- Anotaciones para el tipo de devolución: anotar el tipo de devolución es ligeramente diferente de anotar los argumentos de la función. El ‘->’ es seguido por expresión que es seguido por ‘:’. La sintaxis de anotación del tipo de devolución se muestra a continuación.
def foobar(a: expression)->expression:
Gramática
decorator : ‘@’ name_ [‘(’ [arglist] ‘)’] NEWLINE decorators : decorator+ funcdef : [decorators] ‘def’ NAME parameters [‘->’] ‘:’ suite parameters : ‘(’ [typedarglist] ‘)’ typedarglist : (( tfpdef [‘=’ test] ‘, ’)* (‘*’ [tname] (‘, ’ tname [‘=’ test])* [‘, ’ ‘ **’ tname] | ‘**’ tname) | tfpdef [‘=’ test (‘, ’ tfpdef [‘=’ test])* [‘, ’]]) tname : NAME [‘:’ test] tfpdef : tname | ‘(’ tfplist ‘)’ tfplist : tfpdef (‘, ’ tfpdef)* [‘, ’]
Gramática de visualización: el árbol de análisis se forma a partir de la gramática anterior para brindar una mejor visualización de la sintaxis de la función de Python y las anotaciones de función.
Código de muestra
El siguiente código aclarará el hecho de que las anotaciones de la función no se evalúan en tiempo de ejecución. El código imprime series de fibonacci hasta las posiciones ‘n’.
# Python program to print Fibonacci series def fib(n:'int', output:'list'=[])-> 'list': if n == 0: return output else: if len(output)< 2: output.append(1) fib(n-1, output) else: last = output[-1] second_last = output[-2] output.append(last + second_last) fib(n-1, output) return output print(fib(5))
Output: [1, 1, 2, 3, 5]
Nota: Las anotaciones de funciones solo se admiten en python 3x.
Acceso a anotaciones de funciones
1. Uso de ‘__anotaciones__’ : se puede acceder a las anotaciones de función en el código anterior mediante un atributo especial ‘__anotaciones__’. Muestra el diccionario con una tecla especial ‘retorno’ y otras teclas con el nombre de los argumentos anotados. El siguiente código imprimirá las anotaciones.
# Python program to illustrate Function Annotations def fib(n:'int', output:'list'=[])-> 'list': if n == 0: return output else: if len(output)< 2: output.append(1) fib(n-1, output) else: last = output[-1] second_last = output[-2] output.append(last + second_last) fib(n-1, output) return output print(fib.__annotations__)
Output: {'return': 'list', 'n': 'int', 'output': 'list'}
2. Uso del módulo estándar ‘pydoc’ : el ‘pydoc’ es un módulo estándar de Python que devuelve la documentación dentro de un módulo de Python (si corresponde). Tiene un método especial de ‘ayuda()’ que proporciona un shell interactivo para obtener ayuda sobre cualquier palabra clave, método, clase o módulo. ‘ayuda()’ se puede utilizar para acceder a las anotaciones de la función. La siguiente imagen muestra las anotaciones de funciones en el código de la serie de Fibonacci anterior. El nombre del módulo es ‘fib.py’.
3. Uso del módulo estándar ‘inspeccionar’ : el módulo ‘inspeccionar’ proporciona varias funciones útiles para ayudar a obtener información sobre objetos vivos, como módulos, clases, métodos, funciones, rastreos, objetos de marco y objetos de código. Podemos usar el método ‘getfullargspec’ del módulo para obtener información completa sobre la función que contendrá las anotaciones.
# Python program to illustrate Function Annotations import inspect def fib(n:'int', output:'list'=[])-> 'list': if n == 0: return output else: if len(output)< 2: output.append(1) fib(n-1, output) else: last = output[-1] second_last = output[-2] output.append(last + second_last) fib(n-1, output) return output print(inspect.getfullargspec(fib))
Output: FullArgSpec(args=['n', 'output'], varargs=None, varkw=None, defaults=([], ), kwonlyargs=[], kwonlydefaults=None, annotations= {'output': 'list', 'return': 'list', 'n': 'int'})
Aplicación de anotaciones de funciones
- Uso de ‘mypy’: ‘mypy’ es una biblioteca externa que proporciona verificación de tipos estáticos con la ayuda de anotaciones de funciones.
Descargar mypy para python 2x
pip install mypy
python 3x
pip install git+git://github.com/JukkaL/mypy.git
Ejemplo 1:# String slicing function that returns a string from start index to end index.
def
slice
(string:
str
, start:
int
, end:
int
)
-
>
str
:
return
string[start:end]
slice
([
1
,
2
,
3
,
4
,
5
],
2
,
4
)
Guarde el código anterior como ejemplo.py y ejecute el siguiente comando después de la instalación de mypy. Asegúrese de estar en el directorio donde guardó el archivo.
mypy example.py
Obtendrá el siguiente resultado.
- Las cosas son un poco diferentes cuando los decoradores están involucrados.
Ejemplo 2 (parte a): Comprobación de tipo de los parámetros de la función envuelta ‘gift_func’ y ‘wrapped’def
wrapping_paper(func):
def
wrapped(gift:
int
):
return
'I got a wrapped up {} for you'
.
format
(
str
(func(gift)))
return
wrapped
@wrapping_paper
def
gift_func(giftname:
int
):
return
giftname
print
(gift_func(
'gtx 5000'
))
Al principio, puede parecer que pasar una string como argumento devolverá un error ya que el tipo de datos requerido es un ‘int’ como se indica en ‘gift_func’ y ‘wrapped’. mypy no establece la verificación de tipos en los parámetros de la función envuelta, sin embargo, se puede verificar la verificación de tipos del decorador y el tipo de retorno de las funciones envueltas. Por lo tanto, se puede esperar el siguiente resultado del código anterior.
- Ejemplo 2 (parte b): Comprobación de tipo de los parámetros del decorador ‘wrapping_paper’.
def
wrapping_paper(func:
str
):
def
wrapped(gift:
int
):
return
'I got a wrapped up {} for you'
.
format
(
str
(func(gift)))
return
wrapped
@wrapping_paper
def
gift_func(giftname:
int
):
return
giftname
print
(gift_func(
'gtx 5000'
))
Ahora obtendrá el siguiente resultado.
- Ejemplo 2 (parte c): Comprobación de tipo del tipo de devolución de ‘gift_func’ y ‘wrapped’
# Suppose we want the return type to be int
from
typing
import
Callable
def
wrapping_paper(func):
def
wrapped(gift)
-
>
int
:
return
'I got a wrapped up {} for you'
.
format
(
str
(func(gift)))
return
wrapped
@wrapping_paper
def
gift_func(giftname)
-
>
int
:
return
giftname
print
(gift_func(
'gtx 5000'
))
Obtendrá el siguiente resultado.
- Ejemplo 2 (parte d) Comprobación de tipo del tipo de retorno de la función contenedora ‘wrapping_paper’
# Suppose we want the return type to be int
from
typing
import
Callable
def
wrapping_paper(func)
-
>
int
:
def
wrapped(gift):
return
'I got a wrapped up {} for you'
.
format
(
str
(func(gift)))
return
wrapped
@wrapping_paper
def
gift_func(giftname):
return
giftname
print
(gift_func(
'gtx 5000'
))
Obtendrás el siguiente resultado
Este artículo es una contribución de Anmol Chachra . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA