Annotations en Python
Python est un langage de programmation robuste et typé dynamiquement. Il a une syntaxe simple similaire à l’écriture d’un anglais simple et s’appuie sur un vaste pool de bibliothèques et de fonctionnalités.
L’une de ces fonctionnalités est les annotations. Les annotations sont des expressions Python arbitraires qui donnent des indications sur le type de données des variables, les paramètres de fonction et le type de retour de fonction.
Les annotations visent à améliorer la lisibilité et la compréhension du code source et sont interprétées par des bibliothèques tierces pour fournir des services efficaces et rapides tels que des conseils de syntaxe, la vérification du type de données, le conseil de type de données dans les IDE ou l’auto-complétion des environnements de développement intégrés. code et la génération de documentation automatisée ou pilotée par l’IA.
Il existe deux types d’annotations en Python : les annotations de fonction et les annotations de variable. Dans cet article, nous parlerons des deux types d’annotations en Python à l’aide d’exemples pertinents.
Annotations de variables en Python
Les annotations de variables sont des expressions qui visent à fournir des détails sur les types de données des variables en Python. Les annotations variables ont la syntaxe suivante.
<variable > : < expression > = < initial value >
Les expressions d’annotations sont écrites entre le nom de la variable et sa valeur initiale, préfixée par deux-points ou :
. Regardons quelques exemples pour mieux comprendre cela. Reportez-vous au code Python suivant.
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)
Production :
name: Vaibhav
age: 20
language: Python
student: True
height: 5.9
Dans l’exemple ci-dessus, nous utilisons des types de données Python intégrés pour les expressions. Nous pouvons également utiliser des chaînes et fournir des descriptions détaillées et brèves des variables en place.
Le code Python suivant illustre cela.
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)
Production :
name: Vaibhav
age: 20
language: Python
student: True
height: 5.9
On peut utiliser l’attribut __annotations___
pour accéder à toutes les annotations.
Cet attribut est un dictionnaire où les clés sont les variables et les valeurs sont les expressions d’annotations. Notez que cet attribut fournira uniquement des détails sur les variables et non sur les fonctions.
Reportez-vous au code Python suivant pour cela.
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__)
Production :
{'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'}
Pour le premier exemple, la sortie sera la suivante.
{'name': < class 'str' > , 'age': < class 'int' > , 'language': < class 'str' > , 'student': < class 'bool' > , 'height': < class 'float' > }
Jusqu’à présent, nous n’avons discuté que des types de données primitifs tels que int
, float
et str
.
Voyons maintenant comment écrire des expressions d’annotation pour des types de données complexes tels que list
, tuple
, set
, list
d’objets, etc. Pour cela, nous allons utiliser le module typing
.
Le module typing
fait partie de la bibliothèque standard de Python. Comprenons comment l’utiliser pour des types de données complexes à l’aide d’un exemple.
Reportez-vous au code Python suivant pour cela.
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__)
Production :
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]]}
Le module typing
a des classes List
, Tuple
et Set
pour List
, Tuple
et Set
, respectivement, qui agissent comme leurs versions génériques. En dehors de ces trois classes, il existe d’autres classes génériques, telles que Dict
, FrozenSet
, DefaultDict
et OrderedDict
.
Ces classes génériques peuvent être utilisées pour fournir des expressions d’annotations pour les variables. À côté de ces classes, entre crochets []
, des types de données primitifs, des descriptions de chaînes, des classes ou d’autres classes génériques du même module sont placés.
Notez qu’ils peuvent être utilisés pour fournir des expressions pour les fonctions, ce que nous apprendrons dans un instant. Pour en savoir plus sur le module typing
, reportez-vous à la documentation officielle ici.
Annotations de fonctions en Python
Les annotations de fonction sont des expressions qui visent à fournir des détails sur les types de données des paramètres fonctionnels et les types de données des valeurs de retour des fonctions en Python. Les annotations de fonction ont la syntaxe suivante.
def function( < parameter > : < expression > , < parameter > : < expression > = < default value > ) -> <expression > :
Les expressions d’annotation sont placées à côté des paramètres séparés par deux-points ou :
.
S’il existe des valeurs par défaut, elles sont placées après les expressions d’annotation. Pour les types de retour des fonctions, la signature de la fonction est suivie d’un ->
ou d’une flèche et de l’expression d’annotation.
Notez que le côlon est placé à la toute fin. Comprenons les annotations de fonction à l’aide de quelques exemples pertinents.
Reportez-vous au code Python suivant pour la même chose.
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__)
Production :
{'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]}
Comme nous pouvons le voir, la fonction create_user()
accepte trois valeurs, à savoir name
, age
et hobbies
, et renvoie un dictionnaire ou dict
.
La méthode create_users()
accepte une liste de tuples représentant une liste d’utilisateurs. Cette méthode renvoie une liste de dictionnaires.
Le résultat de l’appel de la méthode create_user()
est stocké dans une variable u1
, qui est de type dict
. Et, le résultat de l’appel de la fonction à la méthode create_users()
est stocké dans une variable users
, qui est de type List[dict]
.
L’attribut __annotations__
ne fournira que des détails sur les variables. Pour récupérer les détails des annotations sur les fonctions, nous pouvons utiliser l’attribut __annotations__
.
Le code Python suivant illustre cela.
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__)
Production :
{'name': <class 'str'>, 'age': <class 'int'>, 'hobbies': typing.List[str], 'return': <class 'dict'>}
{'users': typing.List[typing.Tuple], 'return': typing.List[dict]}
Le dictionnaire de sortie inclura tous les détails d’annotation. Notez que pour le type de retour, return
est la clé dans le dictionnaire. Pour les paramètres, les noms des paramètres sont les clés.