来源:https://www.python.org/dev/peps/pep-0591/
添加final目的
- 声明不应重写的方法
- 声明一个类不应该被子类化
- 声明不应重新分配变量或属性
@final 使用方法
- typing.final装饰用来限制使用继承
from typing import final
@final
class Base:
...
class Derived(Base): # Error: Cannot inherit from final class "Base"
...
from typing import final
class Base:
@final
def foo(self) -> None:
...
class Derived(Base):
def foo(self) -> None: # Error: Cannot override final attribute "foo"
# (previously declared in base class "Base")
...
- 对于overload重载的方法,应将@final放在实现上。
被overload装饰的函数的输入类型和输出类型可以有多种,但是,最后的实现方法一定要通用,也就是没有类型注解。
overload仅仅是给检查工具用的。但如果静态类型检查变成项目的一部分的话,会避免很多问题。
from typing import Any, overload
class Base:
@overload
def method(self) -> None:
...
@overload
def method(self, arg: int) -> int:
...
@final
def method(self, x=None): # 不能添加类型注释
...
- 在非方法函数上使用@final是错误的。
Final 声明变量使用
- 使用形式:
对于显式类型,使用语法Final [<type>]
ID:Final [float] = 1
或 不用类型注释
ID:Final= 1
- 作为self.id:Final = 1(也可以选择带有方括号的类型)。仅在__init__方法中允许这样做,因此最终实例属性在创建实例时仅分配一次。
- final声明的类属性必须在__init__中进行初始化
class ImmutablePoint:
x: Final[int]
y: Final[int] # Error: final attribute without an initializer
def __init__(self) -> None:
self.x = 1 # Good
- Final只能用作赋值或变量注释中的最外面的类型。在其他任何位置使用它都是错误的。特别是, Final不能在函数参数的注释中使用
x: List[Final[int]] = [] # Error!
def fun(x: Final[List[int]]) -> None: # Error!
...
- 声明为final只能保证该名称不会重新绑定到另一个值,但不会使该值不可变
x: Final = ['a', 'b']
x.append('c') # OK