python 的 final 仅为类型提示,无运行时强制不可变性;它仅在 mypy 等静态检查中报错,解释器忽略;Final 不阻止可变对象内容修改,真正不可变需用 tuple、frozen dataclass 等机制。

Python 中的 final 并不是语言内置的“不可变”机制,它本身不提供运行时强制的不可变性,而只是一个类型提示和开发约定。
Final 是类型检查层面的标记
typing.Final 仅在静态类型检查(如 mypy)中起作用。它告诉类型检查器:“这个变量/属性不应被重新赋值”。但 Python 解释器完全忽略它,运行时可以随意修改:
- 例如:from typing import Final
a: Final[int] = 42
a = 100 # mypy 报错,但 Python 运行正常,a 变为 100
类属性与实例属性的行为不同
Final 对类变量和实例变量的约束力度一致,但实际效果取决于使用方式:
- 标注为
Final的类变量(如MAX_SIZE: Final = 100),mypy 会阻止对它的直接赋值; - 但若通过实例访问(
obj.MAX_SIZE = 200),mypy 通常不会报错(除非开启严格模式),且运行时生效; - 它不阻止对可变对象内容的修改(如
data: Final[list] = [1, 2]→data.append(3)完全合法)。
真正不可变需靠其他机制
若需要运行时不可变,应结合其他手段:
立即学习“Python免费学习笔记(深入)”;
- 使用
tuple、frozenset等内置不可变类型; - 用
@dataclass(frozen=True)冻结数据类,尝试修改属性会抛出FrozenInstanceError; - 自定义
__setattr__或用__slots__配合逻辑控制; - 配合
mypy+ CI 检查,把Final当作协作规范来用。