Instance and class attributes
The mypy type checker detects if you are trying to access a missingattribute, which is a very common programming error. For this to workcorrectly, instance and class attributes must be defined orinitialized within the class. Mypy infers the types of attributes:
- class A:
- def __init__(self, x: int) -> None:
- self.x = x # Aha, attribute 'x' of type 'int'
- a = A(1)
- a.x = 2 # OK!
- a.y = 3 # Error: 'A' has no attribute 'y'
This is a bit like each class having an implicitly definedslots
attribute. This is only enforced during typechecking and not when your program is running.
You can declare types of variables in the class body explicitly usinga type annotation:
- class A:
- x: List[int] # Declare attribute 'x' of type List[int]
- a = A()
- a.x = [1] # OK
As in Python generally, a variable defined in the class body can be usedas a class or an instance variable. (As discussed in the next section, youcan override this with a ClassVar
annotation.)
Type comments work as well, if you need to support Python versions earlierthan 3.6:
- class A:
- x = None # type: List[int] # Declare attribute 'x' of type List[int]
Note that attribute definitions in the class body that use a type commentare special: a None
value is valid as the initializer, even thoughthe declared type is not optional. This should be used sparingly, as this canresult in None
-related runtime errors that mypy can’t detect.
Similarly, you can give explicit types to instance variables definedin a method:
- class A:
- def __init__(self) -> None:
- self.x: List[int] = []
- def f(self) -> None:
- self.y: Any = 0
You can only define an instance variable within a method if you assignto it explicitly using self
:
- class A:
- def __init__(self) -> None:
- self.y = 1 # Define 'y'
- a = self
- a.x = 1 # Error: 'x' not defined