You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.9+中物理单位类型提示的简洁合规实现方案问询

解决方案:为Dataclass物理量添加单位类型提示并通过Mypy检查

问题分析

你尝试用TypeVar/Annotated/NewType标记物理单位时出现三个核心问题:

  • TypeVar是泛型工具,不能直接作为字段类型使用,必须绑定到泛型类或函数。
  • 直接将Annotated赋值给变量后作为类型,Mypy会识别为变量而非合法类型别名。
  • NewType是强类型封装,必须显式构造实例,无法直接接收普通数值类型。

正确实现方案

我们使用Annotated(携带单位元数据)+ 类型别名的方式,配合__post_init__完成单位转换,同时满足Mypy检查要求,且允许__init__直接接收数值类型。

完整代码示例

from dataclasses import dataclass, fields
from typing import Annotated, get_args, get_origin

# 定义带单位元数据的类型别名(符合Mypy类型规范)
Meter = Annotated[float, "meter"]
Um = Annotated[float, "um"]
Ohm = Annotated[float, "ohm"]

# 单位转SI制的系数映射,统一管理转换规则
UNIT_TO_SI = {
    "meter": 1.0,
    "um": 1e-6,
    "ohm": 1.0
}

@dataclass
class Data:
    length_1: Meter = 10e-3  # 默认值已为SI单位(米)
    length_2: Um = 20         # 默认值为微米,将自动转为米
    R: Ohm = 50               # 欧姆为SI单位,无需转换

    def __post_init__(self):
        # 遍历所有字段,自动完成单位转换
        for field in fields(self):
            field_type = field.type
            # 检查字段类型是否为Annotated
            if get_origin(field_type) is Annotated:
                base_type, unit = get_args(field_type)
                # 确认基础类型为数值类型,且单位存在转换规则
                if issubclass(base_type, (int, float)) and unit in UNIT_TO_SI:
                    raw_value = getattr(self, field.name)
                    # 转换为SI单位并覆盖原字段值
                    setattr(self, field.name, raw_value * UNIT_TO_SI[unit])

关键细节说明

  1. 类型别名规范:
    用Annotated[float, "单位"]定义类型别名,Mypy会将其识别为合法类型,同时保留单位元数据。
  2. 单位转换逻辑:
    在__post_init__中通过dataclasses.fields获取字段信息,用get_origin和get_args解析Annotated的元数据,自动完成SI转换,避免重复编写转换代码。
  3. Mypy兼容性:
    • 允许直接传入int/float,因为底层类型是float,Mypy支持int隐式转换为float。
    • 所有类型注解均符合Mypy规范,运行mypy units.py无报错。

原错误修正说明

  • TypeVar误用:TypeVar用于泛型参数绑定,不适合标记单位,替换为Annotated类型别名即可解决“未绑定”错误。
  • Annotated变量问题:直接将Annotated赋值给变量后作为类型,Mypy会视为普通变量;改为类型别名(如Um = Annotated[float, "um"])则符合类型规范。
  • NewType强类型问题:NewType要求显式构造实例(如ohm(50)),不符合你希望直接接收数值的需求,Annotated既保留单位提示,又允许直接使用数值类型。

内容的提问来源于stack exchange,提问作者hoolabandoola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:15:34