Anotaciones en Python
Python es un lenguaje de programación robusto y de tipo dinámico. Tiene una sintaxis sencilla similar a escribir en inglés simple y está respaldado por un grupo masivo de bibliotecas y funciones.
Una de esas características son las anotaciones. Las anotaciones son expresiones arbitrarias de Python que otorgan sugerencias sobre el tipo de datos de las variables, los parámetros de la función y el tipo de retorno de la función.
Las anotaciones tienen como objetivo mejorar la legibilidad y la comprensión del código fuente y son interpretadas por bibliotecas de terceros para proporcionar servicios efectivos que ahorran tiempo, como sugerencias de sintaxis, verificación de tipos de datos, sugerencias de tipos de datos en IDE o autocompletado de entornos de desarrollo integrados. código y generación de documentación automatizada o impulsada por IA.
Hay dos tipos de anotaciones en Python: anotaciones de funciones y anotaciones de variables. En este artículo, hablaremos sobre los dos tipos de anotaciones en Python con la ayuda de ejemplos relevantes.
Anotaciones de variables en Python
Las anotaciones de variables son expresiones que tienen como objetivo proporcionar detalles sobre los tipos de datos de las variables en Python. Las anotaciones de variables tienen la siguiente sintaxis.
<variable > : < expression > = < initial value >
Las expresiones de anotaciones se escriben entre el nombre de la variable y su valor inicial, con el prefijo de dos puntos o :
. Veamos algunos ejemplos para entender esto mejor. Consulte el siguiente código de Python.
name: str = "Vaibhav"
age: int = 20
language: str = "Python"
student: bool = True
height: float = 5.9
print("name:", name)
print("age:", age)
print("language:", language)
print("student:", student)
print("height:", height)
Producción :
name: Vaibhav
age: 20
language: Python
student: True
height: 5.9
En el ejemplo anterior, usamos tipos de datos integrados de Python para expresiones. También podemos usar cadenas y proporcionar descripciones breves y detalladas de las variables en su lugar.
El siguiente código de Python muestra esto.
name: "Name of the person" = "Vaibhav"
age: "Age of the person" = 20
language: "Favorite programming language of the person" = "Python"
student: "Is the person a student?" = True
height: "Height of the person in feet" = 5.9
print("name:", name)
print("age:", age)
print("language:", language)
print("student:", student)
print("height:", height)
Producción :
name: Vaibhav
age: 20
language: Python
student: True
height: 5.9
Podemos usar el atributo __annotations___
para acceder a todas las anotaciones.
Este atributo es un diccionario donde las claves son las variables y los valores son las expresiones de las anotaciones. Tenga en cuenta que este atributo solo proporcionará detalles sobre las variables y no sobre las funciones.
Consulte el siguiente código de Python para esto.
name: "Name of the person" = "Vaibhav"
age: "Age of the person" = 20
language: "Favorite programming language of the person" = "Python"
student: "Is the person a student?" = True
height: "Height of the person in feet" = 5.9
print(__annotations__)
Producción :
{'name': 'Name of the person', 'age': 'Age of the person', 'language': 'Favorite programming language of the person', 'student': 'Is the person a student?', 'height': 'Height of the person in feet'}
Para el primer ejemplo, la salida será la siguiente.
{'name': < class 'str' > , 'age': < class 'int' > , 'language': < class 'str' > , 'student': < class 'bool' > , 'height': < class 'float' > }
Hasta ahora, solo hemos discutido tipos de datos primitivos como int
, float
y str
.
Ahora comprendamos cómo escribir expresiones de anotación para tipos de datos complejos como list
, tuple
, set
, list
de objetos, etc. Para esto, usaremos el módulo typing
.
El módulo typing
es parte de la biblioteca estándar de Python. Comprendamos cómo usarlo para tipos de datos complejos con la ayuda de un ejemplo.
Consulte el siguiente código de Python para esto.
from typing import List, Tuple, Set
def user():
return {"name": "Vaibhav", "username": "vaibhav", "password": "vaibhav"}
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
middlewares: List[str] = []
points: Tuple[Point] = tuple([Point(0, 0), Point(1, 1)])
numbers: Set[int] = set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
users: List[dict] = [user()]
utils: List["function"] = [sum, len, sorted]
pairs: List[List[int]] = [[1, 2], [2, 3], [3, 4]]
print("middlewares:", middlewares, end="\n\n")
print("points:", points, end="\n\n")
print("numbers:", numbers, end="\n\n")
print("utils:", utils, end="\n\n")
print("users:", users, end="\n\n")
print("pairs:", pairs, end="\n\n")
print(__annotations__)
Producción :
middlewares: []
points: (<__main__.Point object at 0x7fc658e454c0>, <__main__.Point object at 0x7fc658cef610>)
numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
utils: [<built-in function sum>, <built-in function len>, <built-in function sorted>]
users: [{'name': 'Vaibhav', 'username': 'vaibhav', 'password': 'vaibhav'}]
pairs: [[1, 2], [2, 3], [3, 4]]
{'middlewares': typing.List[str], 'points': typing.Tuple[__main__.Point], 'numbers': typing.Set[int], 'users': typing.List[dict], 'utils': typing.List[ForwardRef('function')], 'pairs': typing.List[typing.List[int]]}
El módulo typing
tiene las clases List
, Tuple
y Set
para list
, tuple
y set
, respectivamente, que actúan como sus versiones genéricas. Aparte de estas tres, existen otras clases genéricas, como Dict
, FrozenSet
, DefaultDict
y OrderedDict
.
Estas clases genéricas se pueden utilizar para proporcionar expresiones de anotaciones para variables. Junto a estas clases, entre corchetes []
, se colocan tipos de datos primitivos, descripciones de cadenas, clases u otras clases genéricas del mismo módulo.
Tenga en cuenta que se pueden usar para proporcionar expresiones para funciones, que aprenderemos en un momento. Para obtener información sobre el módulo de mecanografía
, consulte la documentación oficial aquí.
Anotaciones de funciones en Python
Las anotaciones de funciones son expresiones que tienen como objetivo proporcionar detalles sobre los tipos de datos de los parámetros funcionales y los tipos de datos de los valores de retorno de las funciones en Python. Las anotaciones de función tienen la siguiente sintaxis.
def function( < parameter > : < expression > , < parameter > : < expression > = < default value > ) -> <expression > :
Las expresiones de anotación se colocan junto a los parámetros separados por dos puntos o :
.
Si hay algún valor predeterminado, se colocan después de las expresiones de anotación. Para los tipos de devolución de funciones, la firma de la función va seguida de un ->
o flecha y la expresión de anotación.
Tenga en cuenta que los dos puntos se colocan al final. Comprendamos las anotaciones de funciones con la ayuda de algunos ejemplos relevantes.
Consulte el siguiente código de Python para lo mismo.
from typing import List, Tuple
def create_user(name: str, age: int, hobbies: List[str] = []) -> dict:
return {"name": name, "age": age, "hobbies": hobbies}
def create_users(users: List[Tuple]) -> List[dict]:
result = []
for user in users:
result.append(create_user(name=user[0], age=user[1], hobbies=user[2]))
return result
u1: dict = create_user("Vaibhav", 20, ["Football", "Video Games"])
data = [
("Rick", 40, ["Shooting"]),
("Derly", 38, ["Archery", "Tracking"]),
("Maggie", 25, []),
("Carol", 32, ["Cooking"]),
]
users: List[dict] = create_users(data)
print(u1)
print(users)
print(__annotations__)
Producción :
{'name': 'Vaibhav', 'age': 20, 'hobbies': ['Football', 'Video Games']}
[{'name': 'Rick', 'age': 40, 'hobbies': ['Shooting']}, {'name': 'Derly', 'age': 38, 'hobbies': ['Archery', 'Tracking']}, {'name': 'Maggie', 'age': 25, 'hobbies': []}, {'name': 'Carol', 'age': 32, 'hobbies': ['Cooking']}]
{'u1': <class 'dict'>, 'users': typing.List[dict]}
Como vemos, la función create_user()
acepta tres valores, a saber, name
, age
y hobbies
, y devuelve un diccionario o dict
.
El método create_users()
acepta una lista de tuplas que representan una lista de usuarios. Este método devuelve una lista de diccionarios.
El resultado de la llamada al método create_user()
se almacena en una variable u1
, que es de tipo dict
. Y, el resultado de la llamada de función al método create_users()
se almacena en una variable users
, que es de tipo List[dict]
.
El atributo __annotations__
solo entregará detalles sobre las variables. Para obtener detalles de las anotaciones sobre las funciones, podemos usar el atributo __annotations__
.
El siguiente código de Python muestra esto.
from typing import List, Tuple
def create_user(name: str, age: int, hobbies: List[str] = []) -> dict:
return {"name": name, "age": age, "hobbies": hobbies}
def create_users(users: List[Tuple]) -> List[dict]:
result = []
for user in users:
result.append(create_user(name=user[0], age=user[1], hobbies=user[2]))
return result
print(create_user.__annotations__)
print(create_users.__annotations__)
Producción :
{'name': <class 'str'>, 'age': <class 'int'>, 'hobbies': typing.List[str], 'return': <class 'dict'>}
{'users': typing.List[typing.Tuple], 'return': typing.List[dict]}
El diccionario de salida incluirá todos los detalles de la anotación. Tenga en cuenta que para el tipo de devolución, return
es la clave en el diccionario. Para los parámetros, los nombres de los parámetros son las claves.