类型转换
实现类型转换魔术方法,让对象支持 int()、float()、bool() 等转换:
class Money:
def __init__(self, amount):
self.amount = amount
def __int__(self):
return int(self.amount)
def __float__(self):
return float(self.amount)
def __bool__(self):
return self.amount != 0
def __repr__(self):
return f"Money({self.amount})"
m = Money(100.5)
print(int(m)) # 100
print(float(m)) # 100.5
print(bool(m)) # True
m0 = Money(0)
print(bool(m0)) # False
核心原理:类型转换内置函数会自动调用对应魔术方法
1. 底层执行逻辑
当你执行 int(obj) / float(obj) / bool(obj) 时,Python 不是直接暴力转换,而是一套固定规则:
int(m)→ 内部会尝试调用m.__int__()float(m)→ 内部会尝试调用m.__float__()bool(m)→ 内部会尝试调用m.__bool__()
魔术方法是协议接口:只要你的类实现了对应名字的双下划线方法,系统内置转换函数就会自动去执行你写的自定义逻辑。
分步拆解 int(m) 完整流程
m = Money(100.5)
print(int(m))
- 调用内置函数
int(m) - Python 查找
m对象有没有定义__int__方法 - 找到你在
Money里写的def __int__(self): return int(self.amount) - 执行该方法,拿到返回值
100作为最终结果
同理:
float(m)触发m.__float__()bool(m)优先触发m.__bool__()
补充 bool 的备用规则(拓展)
如果类没有实现 __bool__,Python 会降级调用 __len__ 判断长度是否为 0;
如果连 __len__ 也没有,默认全部视为 True。
class Test:
def __len__(self):
return 0
t = Test()
print(bool(t)) # False,走__len__
区分:内置函数 和 类魔术方法的关系
int / float / bool 是顶层系统工具函数,它们兼容所有自定义类,靠统一的魔术方法协议实现扩展:
- 原生数字(int/float)内部自带底层逻辑;
- 自定义类想要支持类型转换,只要实现对应
__xxx__魔术方法,系统函数自动适配你的逻辑。
简单类比:
int() 像一个通用转换器,它约定了一套标准:「想要被我转成整数,你就提供 __int__ 方法」。
你的 Money 遵守了这个约定,所以 int(m) 会自动执行你写的代码。
反向验证:删掉魔术方法会报错
把 __int__ 删掉后再执行 int(m):
class Money:
def __init__(self, amount):
self.amount = amount
# 删掉 __int__
m = Money(100.5)
print(int(m))
# TypeError: int() argument must be a string, a bytes-like object or a number, not 'Money'
找不到 __int__ 协议方法,解释器不知道怎么把 Money 对象转整数,直接抛类型错误。




