Python typing Final(类型限定符type qualifier,用于告诉类型检查器:这个变量或属性不应该被重新赋值或被子类覆盖)声明常量、防止子类重写、全大写、实例属性
文章目录
下面是一篇可直接发布的技术博文草稿,面向有一定 Python 基础、希望深入理解类型系统的读者。
深入理解 Python typing.Final
在使用 Python 编写大型项目时,我们经常希望某些变量 只被赋值一次,或者某些方法 不允许在子类中被重写。
Python 的 typing 模块提供了一个重要工具:Final。
本文将介绍:
Final是什么Final的两种核心用途- 常见使用场景
- 与常量的区别
- 实际项目中的最佳实践
1 什么是 Final
Final 是 Python 类型系统中的一个 类型限定符(type qualifier),用于告诉类型检查器:
这个变量或属性 不应该被重新赋值或被子类覆盖。
它最早在 PEP 591 中被提出,并在 Python 3.8 中正式加入 typing 模块。
需要注意:
Final不会在运行时强制限制- 它只对 类型检查工具(例如
mypy、pyright)生效
示例:
from typing import Final
API_VERSION: Final = "v1"
这意味着:
API_VERSION应该只赋值一次- 之后不应该再修改
2 Final 的两种主要用途
Final 主要有 两个核心用途:
1️⃣ 声明常量
2️⃣ 防止子类重写属性
3 用法一:声明常量
这是 Final 最常见的使用方式。
from typing import Final
MAX_CONNECTIONS: Final = 10
如果之后写:
MAX_CONNECTIONS = 20
类型检查工具会报错:
Cannot assign to final name "MAX_CONNECTIONS"
为什么不用普通变量?
传统写法:
MAX_CONNECTIONS = 10
Python 并不会阻止:
MAX_CONNECTIONS = 20
使用 Final 后,类型检查器就能帮助发现问题。
4 用法二:防止子类重写
Final 还可以用于 类属性,防止子类修改。
示例:
from typing import Final
class BaseConfig:
VERSION: Final = "1.0"
子类中如果尝试:
class DevConfig(BaseConfig):
VERSION = "2.0"
类型检查器会提示:
Cannot override final attribute "VERSION"
5 Final 与常量命名规范的区别
在 Python 中,传统的“常量”只是 命名约定:
API_URL = "https://api.example.com"
全大写只是告诉开发者:
“请不要修改它”
但语言本身 不会限制。
而 Final 提供的是:
| 方式 | 是否强制 | 类型检查 |
|---|---|---|
| 命名规范 | 否 | 否 |
Final |
否(运行时) | 是(静态检查) |
因此:
最佳实践是同时使用两者:
API_URL: Final = "https://api.example.com"
6 类属性中的 Final
一个常见场景是 类常量:
from typing import Final
class HttpStatus:
OK: Final = 200
NOT_FOUND: Final = 404
这样:
- 这些值不会被意外修改
- 子类也不会覆盖
7 Final 与实例变量
Final 也可以用于 实例属性:
from typing import Final
class User:
id: Final[int]
def __init__(self, id: int):
self.id = id
这里表示:
id只能在__init__中赋值- 之后不应该再修改
例如:
user.id = 5
类型检查器会报错。
8 Final 不会在运行时生效
这是很多人容易误解的一点。
即使写了:
API_VERSION: Final = "v1"
API_VERSION = "v2"
Python 仍然可以运行。
Final 只是帮助:
mypypyright- IDE(如 PyCharm、VSCode)
进行 静态分析。
9 Final 的典型使用场景
在真实项目中,Final 常见于:
1 配置常量
TIMEOUT: Final = 30
2 API 版本
API_VERSION: Final = "v1"
3 HTTP 状态码
class Status:
OK: Final = 200
4 不希望被子类修改的属性
class BaseService:
NAME: Final = "base"
10 最佳实践
推荐的实践方式:
1 常量同时使用 Final + 大写
DATABASE_URL: Final = "postgres://..."
2 用于不应该改变的配置
例如:
- 端口
- API 版本
- 默认路径
3 在大型项目中使用
Final 在以下情况下最有价值:
- 团队协作项目
- 大型代码库
- 公共库 API
结语
Final 虽然只是 Python 类型系统中的一个小特性,但在 提高代码可维护性和可读性方面非常有价值。
总结:
Final用于声明 不可重新赋值的变量- 可以防止 子类覆盖属性
- 只在 静态类型检查阶段生效
- 推荐与 常量命名规范一起使用
如果你的项目已经开始使用类型检查工具,那么 Final 是一个非常值得引入的工具。
更多推荐


所有评论(0)