Overview
Mypy provides three related features for declaring finality:- Final names — Variables or attributes that should not be reassigned after initialization
- Final methods — Methods that should not be overridden in a subclass
- Final classes — Classes that should not be subclassed
All of these are only enforced by mypy during type checking. There is no runtime enforcement.
Final names
Usetyping.Final to indicate that a name should not be reassigned, redefined, or overridden:
Protecting attributes from override
Final attributes cannot be overridden in subclasses:Syntax variants
You can useFinal in several ways:
- With explicit type
- Without explicit type
- In class bodies
- In __init__
When omitting the type, mypy infers
Literal[1] instead of int. This is more precise than Final[Any].Details of using Final
Two main rules for defining final names:At most one declaration
There can be at most one final declaration per module or class for a given attribute.
Initialization requirements
A final attribute declared in a class body without an initializer must be initialized in__init__:
Restrictions
Final can only be used as the outermost type:
Final vs immutability
Final only prevents reassignment, not mutation:
Final methods
Use@final decorator to protect methods from being overridden:
@final decorator works with:
- Instance methods
- Class methods
- Static methods
- Properties
With overloaded methods
For overloaded methods, add@final on the implementation:
Final classes
Use@final decorator on a class to indicate it should not be subclassed:
When to use final classes
Not designed for subclassing
Not designed for subclassing
The class wasn’t designed to be subclassed. Subclassing might not work as expected or could be error-prone.
Maintain implementation freedom
Maintain implementation freedom
You want to retain the freedom to change the class implementation arbitrarily in the future without breaking subclasses.
Reduce coupling
Reduce coupling
Subclassing would make code harder to understand or maintain by creating tight coupling between base and derived classes.
Invalid: Final abstract classes
An abstract class with@final decorator will generate an error:
Final classes cannot have abstract methods since those attributes could never be implemented.
Overriding final attributes
A final attribute can override a read-only property:Best practices
Use Final for constants
Use Final for constants
Module-level and class-level constants should be marked as
Final to prevent accidental modification.Combine with descriptive names
Combine with descriptive names
Use UPPER_CASE naming for final constants to make them visually distinct.
Use @final for framework code
Use @final for framework code
When building frameworks or libraries, use
@final on methods that shouldn’t be overridden to maintain invariants.Document why something is final
Document why something is final
Add comments explaining why a class or method is marked final to help future maintainers.