Python is well known as a dynamic typing language. This means that every value is checked at runtime without the need to explicitly specify the type of a variable. However, as large projects become more complex and multiple developers collaborate, understanding and maintaining the code can become difficult. To address this, Type Annotation was introduced in Python 3.5. Using type annotations helps improve code readability, prevent bugs, and enhance autocompletion features.
1. Basics of Type Annotation
Type annotation is the syntax that allows explicitly specifying the types of variables or functions. Here are the basic ways to annotate the types of variables and functions:
Variable Annotation:
x: int = 10
y: float = 10.5
name: str = "Alice"
Function Annotation:
def greeting(name: str) -> str:
return "Hello " + name
1.1 Type Annotation of Variables
By specifying the type of a variable, the code writer can clearly indicate which type is expected. This allows for early error detection through static analysis in tooling and IDEs.
1.2 Annotations for Function Parameters and Return Values
Function annotations can explicitly specify the input and output types of a function, helping to anticipate what type of data the function will receive. This is very helpful during code reviews.
2. Built-in Data Types
Python supports various built-in data types, and these types can be used in annotations.
- Basic types like int, float, str, bool, None, etc.
- Container types like List, Dict, Set, Tuple can be further refined using the typing module.
from typing import List, Dict, Tuple
names: List[str] = ["Alice", "Bob", "Charlie"]
scores: Dict[str, int] = {"Alice": 95, "Bob": 85}
position: Tuple[int, int] = (10, 20)
3. Union and Optional
When multiple types are allowed, it is common to use Union
, and when None is allowed, Optional
is used.
from typing import Union, Optional
value: Union[int, float] = 5.5
def get_user(id: int) -> Optional[Dict[str, str]]:
if id == 1:
return {"name": "Alice", "role": "admin"}
return None
4. User-defined Types
When you need to define complex types, using Type
or NewType
allows you to write clearer code.
from typing import NewType
UserID = NewType('UserID', int)
admin_user_id: UserID = UserID(524313)
4.1 Type Alias
Using type aliases allows you to express complex type structures with concise names.
Vector = List[float]
def normalize(vec: Vector) -> Vector:
magnitude = sum(x**2 for x in vec) ** 0.5
return [x / magnitude for x in vec]
5. Generic Types
Using generic types allows a single function or class to work with multiple types. You can define generic types using the typing.Generic
class.
from typing import TypeVar, Generic
T = TypeVar('T')
class Box(Generic[T]):
def __init__(self, content: T) -> None:
self.content = content
int_box = Box(123)
str_box = Box("hello")
6. Advanced Example
Here is a slightly more complex example utilizing type annotations.
from typing import List, Dict, Union, Callable
def process_data(data: List[Union[int, float, str]]) -> Dict[str, Union[int, float]]:
result: Dict[str, Union[int, float]] = {'total': 0, 'numeric_count': 0}
def is_number(val: Union[int, float, str]) -> bool:
return isinstance(val, (int, float))
for item in data:
if is_number(item):
result['total'] += item # Prevents type warnings.
result['numeric_count'] += 1
return result
mixed_data: List[Union[int, float, str]] = [10, '20', 30.5, 'forty', '60', 70.2]
output = process_data(mixed_data)
print(output)
# {'total': 110.7, 'numeric_count': 3}
7. Static Type Checking Tools
Type annotations are most useful when used with static type checking tools. In Python, tools like mypy, Pyright, and Pylance are widely used.
For example, mypy
is used as follows:
mypy script.py
These tools are very effective in checking the type consistency of the code and preventing unexpected type errors.
8. Conclusion
Type annotation is a powerful feature of Python that greatly helps improve code readability, ease maintenance, and prevent errors early. Additionally, when combined with static analysis tools, it provides greater stability for large projects. Through this tutorial, I hope you will be able to effectively utilize type annotations and write more robust Python code.