Typing in Python

Although python is a dynamic typed language, typing (at least type-hinting) is widely used for co-operation, and is occasionally mandatory for the production-level codes.

There are roughly two options: Type Hinting and Mandatory Typing

Table of contents

Type Hinting

Type hinting is a way of adding type information to python code. It does not guarantee the exact types in runtime but it helps co-working because of readability and maintainability. This type hinting is widely used in open source python communities (especially in deep learning communities), because it is easy to communicate and less burdensome compare to mandatory typing.

And also, if you’re using modern IDEs and static analysis tools, you can code easily and less error-prone because IDE’s automation functionalities and static analysis tools read the type hinting.

import typing as T

# Type alias
Members = T.List[str]

class Party:
    def __init__(self, name: str, party_members: Members) -> None:
        self._name: str = name
        self._party_members = party_members

    def join(self, new_members: Members) -> None:
        self._party_members.extend(new_members)

    def __str__(self) -> str:
        return f"Party Name: {self._name}\nMembers: {', '.join(self._party_members)}"

def main():
    lunch_party = Party("Lunch Bunch", ["san", "han"])
    newcomers: Members = ["gyro", "jonathan"]

    lunch_party.join(newcomers)
    print(lunch_party)

if "__main__" == __name__:
    main()

Mandatory Typing

By using pydantic-like library (recommended for production level), we can acheive mandatory typing.

Once pydantic models are defined, it works as structs in C/C++.

Just like C/C++ structs, pydantic models provide a clear and structured way to represent data.

The fields (members in C/C++) and their types makes the data layout explicit and easy to understand.

But unlike C/C++, pydantic does this through runtime validation based on the type hints.


from typing import List
from pydantic import BaseModel

class Party(BaseModel):
    name: str
    members: List[str] = []

    def join(self, new_members: List[str]) -> None:
        self.members.extend(new_members)

    def __str__(self) -> str:
        return f"Party Name: {self.name}\nMembers: {', '.join(self.members)}"


def main():
    lunch_party = Party(name="Lunch Bunch", members=["san", "han"])
    newcomers = ["gyro", "jonathan"]

    lunch_party.join(newcomers)
    print(lunch_party)

    # Example of pydantic validation
    try:
        invalid_party = Party(name="Invalid", members=[1, 2, 3])
    except ValueError as e:
        print(f"Pydantic Validation Error: {e}")

    try:
        lunch_party.join("not a list")
    except ValueError as e:
        print(f"Pydantic Validation Error: {e}")


if "__main__" == __name__:
    main()