Python常量重构:如何构建支持内部引用+未使用属性检测的命名空间?
最优方案:使用独立模块作为命名空间
直接将所有需要共享的常量/属性定义在一个单独的模块(比如constants.py)中,通过导入该模块并使用别名来访问,完全满足你的所有需求:
实现示例
# constants.py from pathlib import Path # 假设DefinedElsewhere是其他地方定义的类 class DefinedElsewhere: def __init__(self, arg: str): self.arg = arg AVOID_MAGIC_NUMBER: int = 10 SOME_TEXT_OUTPUT_MESSAGE: str = 'something' FREQUENTLY_USED_INIT_ARG: str = 'magic initialization argument' THIS_IS_A_WELL_KNOWN_FILENAME: Path = Path('some_hardcoded_filename.txt') BASE_FILENAME: str = THIS_IS_A_WELL_KNOWN_FILENAME.stem HERE_IS_AN_OBJECT = DefinedElsewhere(FREQUENTLY_USED_INIT_ARG)
使用方式
在其他模块中导入并使用:
import constants as my_ns # 访问命名空间内的属性 print(my_ns.AVOID_MAGIC_NUMBER) print(my_ns.BASE_FILENAME)
为什么满足你的需求
- 命名空间隔离:通过模块别名(如
my_ns)访问,完全避免与局部变量、导入符号的命名冲突; - 支持内部引用:模块级变量可以直接引用同一模块中已定义的其他变量(如
BASE_FILENAME引用THIS_IS_A_WELL_KNOWN_FILENAME),执行顺序遵循代码定义顺序; - 未使用检测:所有主流linter(Ruff、Pylint)和类型检查器(Pyright、Mypy)都会自动检测模块中未被任何地方引用的变量,并标记为未使用(比如Ruff的
F841/UNUSED_VARIABLE、Pyright的"Unused variable"提示); - 支持类型注解:模块级变量可以直接添加类型注解,与普通变量的写法一致。
备选方案:使用模块级实例化的类(仅作补充)
如果不想单独创建模块,也可以在当前模块中定义一个类并实例化一次,但这种方案的未使用检测效果不如模块方案:
from dataclasses import dataclass from pathlib import Path class DefinedElsewhere: def __init__(self, arg: str): self.arg = arg @dataclass(frozen=True) class MyNamespace: AVOID_MAGIC_NUMBER: int = 10 SOME_TEXT_OUTPUT_MESSAGE: str = 'something' FREQUENTLY_USED_INIT_ARG: str = 'magic initialization argument' THIS_IS_A_WELL_KNOWN_FILENAME: Path = Path('some_hardcoded_filename.txt') BASE_FILENAME: str = THIS_IS_A_WELL_KNOWN_FILENAME.stem HERE_IS_AN_OBJECT = DefinedElsewhere(FREQUENTLY_USED_INIT_ARG) # 实例化一次作为命名空间 my_ns = MyNamespace()
注意:这种方案下,类的字段(默认值)不会被检测为未使用,只有当你通过my_ns.XXX引用时,若某个属性从未被访问,部分工具可能无法准确检测,因为实例属性的使用跟踪难度更高。因此更推荐使用独立模块方案。
内容的提问来源于stack exchange,提问作者Raúl Núñez de Arenas Coronado
相关产品推荐
相关产品推荐

