Python中如何在class里使用self的装饰器
原本想实现这样的功能
class a:
logs=[]
@self.log()
def b():
print(‘1’)
def log(self,text=’’):
def decorator(func):
@functools.wraps(func)
def wrapper(s, *args, **kw):
self.logs.append(func,args,kw)
return func(*args, **kw)
return wrapper
return decorator
def redo(self):
for _ in self.logs:
_0
但这是错误的,[@self](/user/self).log()会报错 NameError: name 'self' is not defined 也想过把 log 拉出来,不放在 class a 里,有 2 个思路: 1.log 加一个 object 的参数,每次把这个 class 传进去 2.log()用 class 包裹起来,先初始化把 class a 传进去,后来调用就不用加 object 的参数了。
但是遇到问题 思路 1:[@log](/user/log)(self)也是会报错 NameError: name 'self' is not defined 思路 2:没办法所有操作在 class a 内完成,没办法做成包调用
求助 QAQ
Python中如何在class里使用self的装饰器
= =在线等!!
在Python类里用self当装饰器参数,关键得用__get__方法把装饰器变成描述符。直接传self会报错,因为定义时self还不存在。
看这个例子,我们做个记录方法调用次数的装饰器:
import functools
class call_counter:
def __init__(self, func):
functools.update_wrapper(self, func)
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"{self.func.__name__} called {self.count} times")
return self.func(*args, **kwargs)
def __get__(self, obj, objtype=None):
# 这步是关键:把实例方法绑定到类实例
if obj is None:
return self
return functools.partial(self.__call__, obj)
class MyClass:
@call_counter
def my_method(self):
print("Method executed")
@call_counter
def another_method(self, x):
return x * 2
# 使用示例
obj = MyClass()
obj.my_method() # 输出: my_method called 1 times
obj.my_method() # 输出: my_method called 2 times
obj.another_method(5) # 输出: another_method called 1 times
核心是__get__方法:当装饰器被当作实例方法访问时,它返回一个绑定了实例的partial函数。这样调用时就能正确传递self参数了。
还有个更简洁的写法,用类装饰器:
class track_calls:
def __init__(self, method):
self.method = method
self.count = 0
def __get__(self, obj, objtype=None):
def wrapper(*args, **kwargs):
self.count += 1
print(f"{self.method.__name__} called {self.count} times")
return self.method(obj, *args, **kwargs)
return wrapper
用描述符机制解决装饰器访问问题。
头上无数黑线飘过
为什么要这样写装饰器?
TAT 能说说?
log 定义成静态方法或者类方法,然后 @ a.log
#4 你为什么要把装饰器放类里面呀?放类外面不就完了。你调用装饰器的时候用 self 肯定不对啊。
这样?

#4 你如果想取对象里面的变量,也不是这样写的。这个各种教程里面有说,我就不说了。
因为我需要把数据放进 class a 里面去啊 QAQ
变成静态之后得把 a 对象传进去,跟我思路 1 一个问题。。
😃对的就是这个效果😭居然没想到,谢谢!
完。。。全错了
首先 python 装饰器是编译时执行的,而且 self 代表当前类的实例在调用类方法的时候作为第一个参数,self 只是一个约定成俗的写法
self 是在创建对象实例之后调用函数的时候才绑定的,所以在外面是不能用 self 的。改成静态函数,然后把 logs 属性按照类属性来用 a.logs.append 就可以。
哈哈跟#7 一样,谢谢回复
对,我知道。所以我没这样用。。。
懂的
😂这个问题的点不在这里,我的代码里已经解决了这个问题



