Annotations in Python are part of the code that provide metadata and enable
Python is a dynamically typed language instead of a statically typed language. This means that instead of defining data types beforehand, they are determined at runtime based on the values variables contain.
However, variables would mostly be expected to contain specific types of values. This is where annotations come in handy, allowing the programmers to add metadata about what type of value might be expected by which variable.
Note: Annotations are merely added as information for the one reading the code. Python does not inherently implement checks on annotations.
Annotations are defined using the following syntax:
: <datatype>
: Used when being assigned to function parameters or variable assignments.
-> <datatype>
: Used when being assigned to return types.
Let’s study this further using the examples given below.
We can annotate function parameters and variables in the following manner:
# Defining function addition()# The function parameters and return type are annotateddef addition(num1: int, num2: float) -> float:return num1 + num2# Defining function testing()def testing():# Declaring variables and annotating thema: int = 78b: float = 34.5c: double = 90.123d: str = "hello world"print("The values of our variables are as follows:")print("\ta =", a)print("\tb =", b)print("\tc =", c)print("\td =", d)print("\ta + b =", addition(a, b))# Defining function main()if __name__ == "__main__":testing()
Lines 3–4: We define a function addition
that takes two input parameters and returns their sum. We annotate both input parameters and the return value.
The first input parameter, num1
, is annotated as an int
.
The second input parameter, num2
, is annotated as a float
.
The return type is annotated as a float
using ->
.
Lines 10–13: We define four variables, a
, b
, c
, and d
, and annotate them all as variables containing int
, float
, double
, and str
, respectively.
Similarly, we can also use annotations for a class to define the datatypes for its attributes:
# Creating class Studentclass Student:# Declaring attributes and annotating themname: strgrades: dictawards: list# Defining initialization functiondef __init__(self, name: str, grades: dict, awards: list):self.name = nameself.grades = gradesself.awards = awardsif __name__ == "__main__":# Creating a Student instancestudent = Student("Wania",{"Math": 'A', "English": 'D', "Urdu": 'B'},["DHL in semester 2", "Sports woman of the year"])# Printing student attributesprint("Student name:", student.name)print("Student grades:", student.grades)print("Student awards:", student.awards)
Lines 4–6: We annotate the class attributes, annotating name
as a str
, annotating grades
as a dict
, and annotating awards
as a list
.
Lines 9–12: We define the __init__
function, where the function parameters are annotated, as well as their respective types.
Note: As we can see in the example above, annotating in Python is not limited to just data types such as
int
,str
, andfloat
but instead allows for objects such aslist
,dict
,Tuple
, etc., as well.
As we pointed out before, Python does not implement checks for datatypes based on the annotations. As we can see below, we annotate a
as an int
, but instead, give it a string value, and there is no error generated:
# Annotating variable a as int, but assigning it a string valuea: int = "hello world"print(a)
To overcome this shortcoming, we can use external tools such as mypy
and pylint
to check code quality. Once these tools are run over a code file, they generate errors if they spot discrepancies like the one above. Therefore, annotations can be combined with third-party tools to overcome the shortcomings that might be present with just using Python alone.
Free Resources