我正在实现 What is the Python equivalent of static variables inside a function? 中描述的装饰器.在答案中,装饰器具有正常功能,并且在我的环境中也可以使用。
现在我想把装饰器放到一个类方法上。
源代码:
#decorator
def static_variabls(**kwargs):
def new_func(old_func):
for key in kwargs:
setattr(old_func, key, kwargs[key])
return old_func
return new_func
class C:
@static_variabls(counter = 1)
def f_(self) -> None:
print(self.f_.counter)
self.f_.counter += 1
c1 = C()
c1.f_()
c1.f_()
c1.f_()
预期结果:1
2
3
实际结果:1
Traceback (most recent call last):
File "1.py", line 16, in <module>
c1.f_()
File "1.py", line 13, in f_
self.f_.counter += 1
AttributeError: 'method' object has no attribute 'counter'
我不明白为什么这段代码不起作用。根据错误信息,self.f_.counter
不存在,但 print(self.f_.counter)
作品。这里发生了什么事?
最佳答案
c1.f_()
相当于C.f_.__get__(c1, C)()
(由于描述符协议(protocol))。 __get__
返回 method
实际被调用的对象。你附上了counter
到原始函数对象,这不是 method
wraps:包装def new_func
创建的函数.
请注意,对于一个更简单的装饰器,您也有同样的问题,它对属性及其初始值进行了硬编码。
def add_counter(f):
f.counter = 1
return f
class C:
@add_counter
def f_(self) -> None:
print(self.f_.counter)
self.f_.counter += 1
甚至没有装饰器:class C:
def f_(self) -> None:
print(self.f_.counter)
self.f_.counter += 1
f_.counter = 1
关于python - 奇怪的AttributeError仅在赋值时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62968862/