“我希望公开回答这些问题,因为所使用的片段可能会非常误导。”
来源 – https://stackoverflow.com/q/79917832
发布者:罗德里戈·托雷斯
检索于2026年3月31日,许可证 – CC BY-SA 4.0
# 在 types.py 中
type Scalar = bool | int | str |float
SCALAR_TYPES = (bool, int, str, float)
是的,它可以工作,但你所做的只有一部分实际上是“真实”的输入,这一点很重要。
以下是你代码片段的清晰分解
真正可靠和正确的部分
这是完全有效的,并且符合现代输入风格(PEP 695 风格):
type Scalar = bool | int | str | float`
def extract_scalar[T: Scalar](data: dict, key: str, expected: type[T]) -> T: ...
请注意,Scalar 是一个正确的类型别名,而 T: Scalar 是一个约束
这是我推荐的方法
让我们看看什么是有效的,但有点误导
SCALAR_TYPES = (bool, int, str, float)
def extract_scalar[T: SCALAR_TYPES](...) -> T: ...
是的,这段代码可以运行。是的,类型检查器可能会接受它。
但这里有个问题:
SCALAR_TYPES 只是一个运行时元组
它不是一个类型级别的构造
PEP 695 期望约束是字面元组,而不是变量
所以即使 Python 3.14(结合 PEP 649 的延迟注解)在语法上允许这样做,你仍然依赖于以下行为:
不被类型规范保证
在工具之间可能不一致
在未来的更新中容易被破坏
所以,简单来说:你是在将运行时值与类型系统意图混合
实用建议(你应该实际采取的行动)
你的思路是正确的——重用和集中化是好的。只需清晰地划分责任:
# types.py
type Scalar = bool | int | str | float
SCALAR_TYPES = (bool, int, str, float)
然后:
# 类型检查部分
def extract_scalar[T: Scalar](...) -> T: ...
# 运行时验证部分
if not isinstance(value, SCALAR_TYPES):
...
请使用:类型别名进行类型检查,使用元组进行运行时检查
不要试图让一个同时完成这两项工作。
更多
《512K行泄露的Claude代码让我对AI工具设计的启示》
在2026年3月31日,Anthropi
澳大利亚建筑许可证数据是一座金矿。我们用它构建了什么。
每当澳大利亚有人想要建造游泳池、拆除房屋