Type Hints Convention for Instance Variables Python

Viewed 10817

I'm unsure of the Python convention for type hinting instance variables - I've been doing them within the __init__ constructor arguments like seen here:

class LoggedVar(Generic[T]):
    def __init__(self, value: T, name: str, logger: Logger) -> None:
        self.name = name
        self.logger = logger
        self.value = value`

But I also see the PEP conventions of annotating instance variables as such (snippet below) and then also doing type hinting within the __init__ arguments:

class BasicStarship:
    captain: str = 'Picard'               # instance variable with default
    damage: int                           # instance variable without default
    stats: ClassVar[Dict[str, int]] = {}  # class variable`

    def __init__(self, damage: int, captain: str = None):
        self.damage = damage
        if captain:
            self.captain = captain  # Else keep the default

Lastly, later on in the PEP 526 article they say one can do the following for convenience and convention:

class Box(Generic[T]):
    def __init__(self, content):
        self.content: T = content

(Both of the above code snippets are from here.)

So — is one of these conventions better/more widely accepted than the others that I should try to stick to (better readability etc..)?

3 Answers

@Asara

It seems that as of Python 3.8.10 / Mypy 0.910 (Sep 2021), when it comes to distinguishing between a type annotation for an instance variable in a class definition and a declaration for a class (static) variable in a class definition, the assignment of a default value makes all the difference. If you do not assign a default (e.g., x: int), Python treats the expression as a type annotation; if you assign a default (e.g., x: int = 42), Python treats the expression as a class (static) variable declaration.

It is possible to create a type annotation for a class (static) variable in a class definition, using the ClassVar syntax. If you do not assign a default (e.g., y: ClassVar[int]), a factual class (static) variable will not be created; if you assign a default (e.g., y: ClassVar[int] = 69), a factual class (static) variable will be created.

Related