我试图在我的方法中实现一个所谓的静态变量,类似于 decorator method described in this Stackoverflow thread .具体来说,我定义了一个装饰器函数如下:
def static_var(varName, value):
def decorate(function):
setattr(function,varName,value)
return function
return decorate
如示例所示,这可用于将变量附加到函数:
@static_var('seed', 0)
def counter():
counter.seed +=1
return counter.seed
此方法将返回它被调用的次数。
我遇到的问题是,如果我在类中定义方法,这将不起作用:
class Circle(object):
@static_var('seed',0)
def counter(self):
counter.seed +=1
return counter.seed
如果我实例化一个 Circle 并运行 counter,
>>>> myCircle = Circle()
>>>> myCircle.counter()
我收到以下错误:NameError: global name 'counter' is not defined。
我对此的回应是,也许我需要使用self.counter,即
class Circle(object):
@static_var('seed',0)
def counter(self):
self.counter.seed +=1
return self.counter.seed
但是这会产生错误,AttributeError: 'instancemethod' object has no attribute 'seed'。
这是怎么回事?
请您参考如下方法:
您想访问函数对象,但您访问的是一个方法。 Python 将实例和类上的函数视为 descriptors , 在查找时返回绑定(bind)方法。
使用:
@static_var('seed',0)
def counter(self):
self.counter.__func__.seed += 1
到达包装的函数对象。
在 Python 3 中,您还可以访问类上的函数对象:
@static_var('seed',0)
def counter(self):
Circle.counter.seed += 1
在 Python 2 中,它仍然会返回一个未绑定(bind)的方法对象(一个没有附加实例的方法)。
当然,仅仅因为您可以做到这一点,并不一定就是一个好主意。使用一种方法,您就有了一个类,为您提供了一个替代位置来存储该计数器。您可以将它放在 Counter 或 type(self) 上,后者将为您每个子类 提供一个计数器。
