As we all know, Python is a dynamically typed language. This means we don’t have to provide any specific- data types for variables or function return values. In Python 3.5, type hints were introduced to make Python feel statically typed. The primary purpose of adding a typing module to Python is to get the benefits of better debugging using Python typecheckers like mypy and better code documentation for easier readability. In this article, we shall see how we can use TypedDict from typing module in Python.
Installation of Python TypedDict
TypeDict is included in Python 3.8 and can be directly imported from typing.
from typing import TypeDict
Python typing_extensions typeddict
If you are using anything below python 3.8, you would have to install typing_extensions using pip to use the TypedDict. By using the below write command, you can install typing_extensions.
pip install typing_extensions
Python typeddict vs dict
The dict [key: value] type lets you declare uniform dictionary types, where every value has the same type, and arbitrary keys are supported. But The TypedDict allows us to describe a structured dictionary/map where the type of each dictionary value depends on the key like songs like in the below given example.
songs = {'name':we will rock you','year':1977} #typical dictionaries
Python TypedDict In-Depth Examples
TypedDict was introduced in Python 3.8 to provide type Hints for Dictionaries with a Fixed Set of Keys. The TypedDict allows us to describe a structured dictionary/map with an expected set of named string keys mapped to values of particular expected types, which Python type-checkers like mypy can further use. Using an example, let’s look at the class-based syntax of TypedDict.
from typing import TypedDict
class Songs(TypedDict):
name : str
year : int
In this example, Songs is a TypedDict with two items name(type str) and year(type int).
Python typeddict attribute
So, let’s take a look at TypedDict attributes. Attributes are the variables that you included in the typeddict.
In the above-given example that we created, Songs name(type str) and year(type int) are the attributes.
Default value in Python typeddict
Above we created TypeDict Songs. Let’s see how we can use it. We can use it in several ways. At the same time, we were defining a simple Python Dictionary.
song: Songs = {'name': 'We Will Rock You' , 'year':1977}
We can also use type Songs in function returns.
def song_info(name,year) -> Song:
return {'name': name, 'year': year}
print(song_info("we will rock you",1977))
Output
{'name': 'we will rock you', 'year': 1977}
We can also use type Songs to predefine a variable
song_info : Songs
song_info = {'name':"we will rock you",'year': 1977}
Python typeddict instance Vs typeddict class
TypedDict can be used as an instance, or we can create custom classes by using inheritance. The TypedDict instance can be used just like any other python instance. Here is an example of TypedDict instance:
#typeddict instance example
randomType = TypedDict('someName', {'key': type})
TypedDict class can be by defining a python class and then inheriting the TypedDict and then defining the required parameters according to your needs. Here is an example of TypedDict class:-
#typeddict class example
class randomType(TypedDict):
key: int
The key difference here is that the TypedDict instance does not support inheritance while TypedDict class will, which can help define various TypedDict.
Python typeddict total=false
Total is a functionality present in TypedDict where we can override the default rules that all keys must be present in the TypedDict. Defining total=False allows us to omit any keys without errors. Let’s better understand these using an example.
from typing import TypedDict
class Songs(TypedDict):
name: str
year: int
song_info: Songs = {'name': 'we will rock you'}
# Error : 'year' missing
But by adding total=False argument to TypedDict. We can omit specified keys.
from typing import TypedDict
class Songs(TypedDict,total=False):
name: str
year: int
song_info: Songs = {'name': 'we will rock you'}
Python TypeDict Inheritance
We can also reuse the TypeDict Songs by inheriting them in any other class.
from typing import TypedDict
class Songs(TypedDict):
name : str
year : int
class Band_Name(Songs):
band_name:str
song_info:Band_Name = {'name': we will rock you','year':1977,'band_name':'Queens'}
Using Inheritance band_name now has a name, a year from Songs.
We can also use inheritance by adding required and non-required (total=False) together into one class. Let’s see using an example for better understanding.
from typing import TypedDict
class Songs(TypedDict):
name : str
year : int
class Band_Name(Songs,total=False):
band_name:str
song_info:Band_Name = {'name': we will rock you','year':1977} # now band_name is optional
Examples of Multiple inheritances
class A(TypedDict):
a: str
class B(TypedDict):
b: str
class abc(X, Y):
c: int
The TypedDict ABC has three items: a (type str), b (type str), and c (type int).
However, a TypedDict cannot inherit from both a TypedDict type and a non-TypedDict base class.
Python typeddict nested
Using inheritance, we can create complex TypedDict to type-hint nested objects in Python. For these, each class would have to be a subclass of TypedDict.
from typing import List, TypedDict, Optional, Dict
class Song_info(TypedDict):
name: str
year: int
class Band_info(TypedDict):
no_of_members: int
lead_singer: str
class Songs(TypedDict):
songs_info:Song_info
band: Band_info
result:Songs = {'songs_info':{'name':'we will rock you','year':
1977},'band':{'no_of_members':4,
'lead_singer':'Freddie Mercury'}}
How to convert python typeddict to dict?
Now let’s look at how we can convert a python TypedDict to dict.
#python typeddict to dict.
from typing import TypedDict
class AB(TypedDict):
a: str
b: int
d = AB({"a": "foo", "b": 1})
d = dict(d)
print(d)
Explanation
So as given in the above example, first, we create a TypedDict. We have created AB TypedDict, and then we are using it in a python dict and then using dict( ) function, we can convert TypedDict into dict.
How to convert python typeddict to json?
Let’s take a look at how we can convert TypedDict into JSON.
#python typeddict to json
from typing import TypedDict
import json
class AB(TypedDict):
a: str
b: int
d = AB({"a": "foo", "b": 1})
jsonstr = json.dumps(d)
print(d)
Explanation
So as given in the above example, first, we create a TypedDict. We have created AB TypedDict, and then we are using it in a python Dictionary and then using the json.dumps( ) function we converting that dictionary into json.
Supported Operations
The TypedDict supports also supports some of the methods and operations of the Python dictionary. But we must use the string while calling these methods, or else typecheckers like mypy won’t be able to recognize if the key is valid or not. List of supported operations by The TypedDict:
- Anything included in
Mapping
.for key in
A(iteration)- A.get(keys[,default])
- A.keys( )
- A.values( )
- A.items( )
Unions of TypedDicts
Since TypedDict are regular dicts, we cannot use isinstance with TypedDict to differentiate between different Union of TypedDicts like we can with regular dicts. Python will raise a runtime error of TypeError
.
FAQs on Python typeddict
TypedDict objects are standard dictionaries at runtime. Therefore, TypedDict cannot be used with other python dictionary classes or mapping classes, including subclasses of dict.
When was TypeDict added in Python?
TypedDict was added into Python in the 3.8 version in the typing module.
We should prefer TypedDict when we have dictionaries where the type of each dictionary value depends on the key.
Conclusion
- The TypedDict can be very useful in detecting errors when paired with mypy
- It can also help in increasing the code readability.
- By using total=False can allows in complex and wide varitey of static typechecking.