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

如何从类方法的装饰器内部获取实例引用?

装饰器内部获取类实例引用的解决方法

你的判断完全正确:装饰器是在类定义阶段执行的,此时传入装饰器的initial_method只是一个未绑定到任何实例的普通函数对象,自然没有__self__属性。只有当你通过实例调用方法时,Python才会自动把函数包装成绑定方法,并将实例作为第一个参数传入。

要在装饰器内部拿到实例引用,有两种可靠的方式:

1. 直接从包装函数的参数中获取

实例方法调用时,第一个参数默认就是实例本身(也就是我们常写的self),直接在包装函数里定义或提取即可:

def decor(initial_method):
    def wrapped_method(self, *args, **kwargs):
        # 这里的self就是当前调用方法的实例引用
        print(f"当前实例:{self}")
        # 调用原方法,记得传入self
        return initial_method(self, *args, **kwargs)
    return wrapped_method

class A:
    @decor
    def f2(self):
        pass

A().f2()  # 输出类似:当前实例:<__main__.A object at 0x10ebfd7f0>

如果要兼容手动调用类方法(比如A.f2(obj))的场景,可以通过args动态提取第一个参数:

def decor(initial_method):
    def wrapped_method(*args, **kwargs):
        if args:
            instance = args[0]
            print(f"当前实例:{instance}")
        return initial_method(*args, **kwargs)
    return wrapped_method

2. 补充:为什么外部能拿到__self__

当你执行A().f2.__self__时,实际上是先创建了实例,然后访问实例的f2属性——此时Python会把装饰后的wrapped_method包装成绑定到该实例的方法对象,所以这个方法对象才有__self__属性。但装饰器内部的initial_method是类定义时就传入的原函数,从未被绑定到实例,所以始终没有__self__。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:39:18