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

Python类装饰器执行逻辑疑问:为何调用函数时仅触发__call__方法

核心原理铺垫

当使用类作为装饰器时,Python会在装饰阶段自动执行一次被装饰函数 = 类名(被装饰函数):

  1. 这个执行逻辑只会触发类的__init__方法,将原函数作为参数传入__init__的func参数
  2. 执行完成后,你代码里的myFunc已经不是原来的函数,而是Log_dec类的实例对象

疑问1解答

Python有固定的魔法方法触发规则:只有当你把类实例像函数一样调用(即写实例(参数)格式)时,才会自动触发类定义的__call__魔法方法。
你自定义的__CallTwice__不属于Python内置魔法方法,没有任何自动触发逻辑,你调用myFunc('Haha')时,参数自然只会传给__call__的args参数,完全不会和__CallTwice__产生关联。
如果要执行__CallTwice__,你需要主动调用:

myFunc.__CallTwice__('Haha')

运行后会输出:

do something different
My Name is Haha

疑问2解答

__init__和__CallTwice__虽然参数定义格式类似,但触发逻辑完全不同:

  • __init__是类的构造方法,装饰器运行阶段Python会自动传入原函数作为它的参数
  • __CallTwice__是你自定义的普通类方法,没有任何内置逻辑会自动给它传参,你不主动调用的情况下这个方法根本不会执行,自然也不会收到原函数或者调用时传入的'Haha'参数

补充优化建议

你当前的__call__方法只支持传入1个位置参数,如果要兼容任意参数的被装饰函数,可以修改定义为:

def __call__(self, *args, **kwargs):
    print('do something before function')
    result = self.func(*args, **kwargs)
    print(result)
    print('do something after function')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:09:04