,

python 魔术方法

类型转换 实现类型转换魔术方法,让对象支持 int()、float()、bool() 等转换: 核心原理:类型…

类型转换

实现类型转换魔术方法,让对象支持 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 不是直接暴力转换,而是一套固定规则:

  1. int(m) → 内部会尝试调用 m.__int__()
  2. float(m) → 内部会尝试调用 m.__float__()
  3. bool(m) → 内部会尝试调用 m.__bool__()

魔术方法是协议接口:只要你的类实现了对应名字的双下划线方法,系统内置转换函数就会自动去执行你写的自定义逻辑。

分步拆解 int(m) 完整流程

m = Money(100.5)
print(int(m))
  1. 调用内置函数 int(m)
  2. Python 查找 m 对象有没有定义 __int__ 方法
  3. 找到你在 Money 里写的 def __int__(self): return int(self.amount)
  4. 执行该方法,拿到返回值 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 对象转整数,直接抛类型错误。

Previous Post

Next Post

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor