Understanding Type Annotation In Python

June 27, 2023
Understanding Type Annotation in Python

Python, being a dynamically-typed language, has its pros and cons. Yes, it enables developers to color indentation, code, and documentation their way, but freedom often creates a mess. The complexity-reducing trick to designate types with variables on the go makes it easy to code but hard to read the code.

So, Python 3.5 introduced a new feature to inject clarity into the mix; Python annotations. The feature lets developers add type hints to previously cryptic variables, bringing a statically-typed feel to dynamically-typed language.

Python annotations or type annotations in Python lets developers declare a type after a variable or method to clarify what it is, what it can do, and what it can’t.

python CTA2

Why Use Python Annotations?

Pro coders prefer statically-typed languages as they help them keep ambiguity in check and enforce some ground rules for better readability and performance. For instance, the string must be str, and integers must be ints.

Dynamically-typed languages like Python takes a different approach and doesn’t restrict a variable to a specific domain or type. Here, Python annotations come into play. Using type hints, they clarify the variable on the spot.

Annotating Variables in Python

Below is an example of annotating variables in Python:

     my_var: <type> = <value>

The format adds <type> right next to the variable my_var and defines the default <value>.

Let’s review a simple example:

age: int=5


# 5

Remember, type annotations in Python has no effect on the program’s runtime, as the interpreter ignores them. However, as they go through unenforced, it is doubly important to be vigilant and type correct types, or else their inclusion will only curb readability.

Python Annotations: Annotating Functions

In Python, ill-defined variables often produce unexpected results. For instance, passing str when the function expects int skews the output entirely.

 def puzzle_combine(a, b, times):

     return (a + b) * times

In the syntax above, it is clear what the function puzzle_combine does, but the variables a, b, and times are unclear. Let’s call the above code with two different arguments and observe the output (in the comments).

 # Original Function 
 def puzzle_combine(a, b, times):

     return (a + b) * times

 print(puzzle_combined(3, 4, 4))

 # 28

 print(puzzle_combined(‘Hello ‘, ‘Xperti! ‘, 4))

 #  Hello Xperti! Hello Xperti! Hello Xperti! Hello Xperti!

In both cases, the function produces two entirely different results. Integers made it carry PEMDAS mathematics, while strings made two variables, Hello and Xperti! merge and repeat times times.

So, if the developer had expected the function to function in ways it did with strings, adding integers would ruin the output. Here, enforcing a domain or type using Python annotations is a must.

 def puzzle_combine(a: str, b: str, times: int) -> str:

      return (a + b) * times

A simple inclusion of type annotations in Python goes a long way in enhancing the readability of the code and ensuring the functions function correctly.

Python Annotations: Annotating Methods

Python annotations work the same way with methods as they do with functions. However, it is not necessary to annotate everything. For instance, leaving self unannotated is better as it is an instance of the class itself.

 class WordBuilder:

     suffix = 'World'

     def puzzle_combine(self, a: str, times: int) -> str:

         return (a, self.suffix) * times

The above code is much like the function-based example, except suffix attribute in the WordBuilder has replaced the parameter b. Like self, it is also unnecessary to add a type annotation to a suffix, as most code editors can decode it.

Types of Python Annotation

Having explored some use cases of type annotations in Python, it is time to turn to types. In short, annotations can be classified further into basic and complex.

Basic Type Annotations in Python

The simplest way to annotate is via class type. Here are a few built-in class types you can use to define objects.

an_int: int = 3

a_float: float = 1.23

a_str: str = 'Hello'

a_bool: bool = False

a_list: list = [1, 2, 3]

a_set: set = set([1, 2, 3])  # or {1, 2, 3}

a_dict: dict = {'a': 1, 'b': 2}

 # They also work with defined classes 

class AnyClass:    


 instance: AnyClass = AnyClass()

Complex Type Annotations in Python

These types use typing to clarify or define variables in detail. Type annotations in Python like Dict, Tuple, List, and Set have them by default. In the example below, typing containers helps elaborate variables within a list.

 from typing import Sequence 

def print_names(names: Sequence[str]) -> None:    

for player in names:      


The above example elaborates on how to add specific domains within lists, like defining the names within a sequence cannot be anything but a string.

Also Read: How To Use Timeit To Profile Python Codes

python CTA



Full Stack Java Developer | Writer | Recruiter, bridging the gap between exceptional talent and opportunities, for some of the biggest Fortune 500 companies.

Candidate signup

Create a free profile and find your next great opportunity.


Employer signup

Sign up and find a perfect match for your team.


How it works

Xperti vets skilled professionals with its unique talent-matching process.


Join our community

Connect and engage with technology enthusiasts.