如何通过__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
相关产品推荐
相关产品推荐

