Python用Enum还是字典映射常量,可免写.value、兼顾类型提示与DRY?
解决方案
方案1:使用StrEnum(Python 3.11+ 推荐)
Python 3.11 标准库新增了StrEnum类型,专门用于字符串枚举场景,成员本身就等价于对应的字符串值,无需额外调用.value,完全匹配你在TypeScript中的使用习惯:
from enum import StrEnum class CompassDirection(StrEnum): NORTH = 'NORTH' SOUTH = 'SOUTH' EAST = 'EAST' WEST = 'WEST' # 直接对比即可返回正确结果 is_equal = CompassDirection.NORTH == 'NORTH' print(is_equal) # 输出 True # 也可以直接当做字符串参与拼接、传参等所有字符串操作 print(f"当前方向: {CompassDirection.NORTH}") # 输出:当前方向: NORTH
该方案完全支持mypy、pyright等主流类型检查工具的类型推断,不需要额外适配。
如果你的Python版本低于3.11,可以自己实现字符串枚举混合类,效果完全一致:
from enum import Enum class StringEnum(str, Enum): pass class CompassDirection(StringEnum): NORTH = 'NORTH'
方案2:常量封装 + Literal 类型约束
如果不想用枚举,也可以用常量组配合Literal实现类型校验,同时避免重复写字符串:
- 首先将同组常量封装到独立命名空间,用
SimpleNamespace可以避免导入过多零散常量:
from types import SimpleNamespace CompassDirection = SimpleNamespace( NORTH = "NORTH", SOUTH = "SOUTH", EAST = "EAST", WEST = "WEST" )
- 配合
Literal做类型限制:
from typing import Literal # 直接复用常量定义类型,避免重复写字符串 CompassDirectionType = Literal[ CompassDirection.NORTH, CompassDirection.SOUTH, CompassDirection.EAST, CompassDirection.WEST ] def move(direction: CompassDirectionType): pass move(CompassDirection.NORTH) # 类型检查通过 move("NORTH") # 类型检查通过 move("invalid") # 类型检查直接报错
该方案的写法和枚举完全一致,取值直接返回字符串,不需要额外调用方法或属性。
方案3:仅用模块级常量
如果你的枚举成员数量不多,也可以直接在独立常量模块中定义变量,使用时按需导入即可:
# constants/compass.py NORTH = "NORTH" SOUTH = "SOUTH" EAST = "EAST" WEST = "WEST"
使用时直接导入对应常量,配合Literal同样可以实现完整的类型推断能力,仅在需要导入多个常量时导入语句会稍长。
内容的提问来源于stack exchange,提问作者A Webb
相关产品推荐
相关产品推荐

