如何从类方法的装饰器内部获取实例引用?
装饰器内部获取类实例引用的解决方法
你的判断完全正确:装饰器是在类定义阶段执行的,此时传入装饰器的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
相关产品推荐
相关产品推荐

