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

如何通过__call__和@property使带单位的类调用时返回普通变量值?

问题分析与解决方案

问题根源

  • print(variable) 会触发对象的 __str__ 魔法方法,而 @dataclass 会自动生成默认的 __str__ 实现,输出格式为类名+所有字段信息(比如 DataUnit(value=1, unit='m/s')),这就是你看到实例信息而非期望数值的原因。
  • 问题和 @dataclass 有关,但并非它的缺陷——只是它生成的默认方法不符合你的需求,本质是没有自定义字符串表示逻辑。

解决方案

要让实例在 print 时输出数值,同时让它更贴近普通变量的行为,可按以下方式修改:

1. 重写 __str__ 和 __repr__

直接覆盖 @dataclass 生成的默认方法,指定输出内容:

from dataclasses import dataclass

@dataclass
class DataUnit:
    value: float
    unit: str

    # 控制print()的输出,返回数值字符串
    def __str__(self):
        return str(self.value)
    
    # 控制交互式环境/调试时的输出(可选,可保留单位信息)
    def __repr__(self):
        return f"{self.value} {self.unit}"

2. 增强类的"变量特性"

如果希望实例能像普通数值一样参与运算、被转换为int/float,或者通过调用行为返回数值,可补充对应的魔法方法:

from dataclasses import dataclass

@dataclass
class DataUnit:
    value: float
    unit: str

    def __str__(self):
        return str(self.value)
    
    def __repr__(self):
        return f"{self.value} {self.unit}"
    
    # 调用实例时返回数值,比如var()得到1
    def __call__(self):
        return self.value
    
    # 支持转换为float类型
    def __float__(self):
        return self.value
    
    # 支持转换为int类型
    def __int__(self):
        return int(self.value)
    
    # 支持同单位的加法运算(示例)
    def __add__(self, other):
        if isinstance(other, (int, float)):
            return DataUnit(self.value + other, self.unit)
        elif isinstance(other, DataUnit) and self.unit == other.unit:
            return DataUnit(self.value + other.value, self.unit)
        raise TypeError("不支持的运算类型")

测试效果

var = DataUnit(1, "m/s")
print(var)          # 输出: 1
print(var())        # 输出: 1
print(float(var) + 3) # 输出: 4.0
print(var + 2)      # 输出: DataUnit(value=3, unit='m/s')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:30:33