Class attribute annotations

You can use a ClassVar[t] annotation to explicitly declare that aparticular attribute should not be set on instances:

  1. from typing import ClassVar
  2.  
  3. class A:
  4. x: ClassVar[int] = 0 # Class variable only
  5.  
  6. A.x += 1 # OK
  7.  
  8. a = A()
  9. a.x = 1 # Error: Cannot assign to class variable "x" via instance
  10. print(a.x) # OK -- can be read through an instance

Note

If you need to support Python 3 versions 3.5.2 or earlier, you haveto import ClassVar from typing_extensions instead (available onPyPI). If you use Python 2.7, you can import it from typing.

It’s not necessary to annotate all class variables usingClassVar. An attribute without the ClassVar annotation canstill be used as a class variable. However, mypy won’t prevent it frombeing used as an instance variable, as discussed previously:

  1. class A:
  2. x = 0 # Can be used as a class or instance variable
  3.  
  4. A.x += 1 # OK
  5.  
  6. a = A()
  7. a.x = 1 # Also OK

Note that ClassVar is not a class, and you can’t use it withisinstance() or issubclass(). It does not change Pythonruntime behavior – it’s only for type checkers such as mypy (andalso helpful for human readers).

You can also omit the square brackets and the variable type ina ClassVar annotation, but this might not do what you’d expect:

  1. class A:
  2. y: ClassVar = 0 # Type implicitly Any!

In this case the type of the attribute will be implicitly Any.This behavior will change in the future, since it’s surprising.

Note

A ClassVar type parameter cannot include type variables:ClassVar[T] and ClassVar[List[T]]are both invalid if T is a type variable (see Defining generic classesfor more about type variables).