我对" Pythonic静态变量使用以下解决方法":
def static_vars(**kwargs):
"""decorator for funciotns that sets static variables"""
def decorate(func):
for k, v in kwargs.items():
setattr(func, k, v)
return func
return decorate
@static_vars(var=1)
def global_foo():
_ = global_foo
print _.var
_.var += 1
global_foo() # >>> 1
global_foo() # >>> 2
它的作用与...一样。但是当我在课堂中移动这样一个装饰的函数时,我得到了一个奇怪的改变:
class A(object):
@static_vars(var=1)
def foo(self):
bound = self.foo
unbound = A.foo
print bound.var # OK, print 1 at first call
bound.var += 1 # AttributeError: 'instancemethod' object has no attribute 'var'
def check(self):
bound = self.foo
unbound = A.foo
print 'var' in dir(bound)
print 'var' in dir(unbound)
print bound.var is unbound.var # it doesn't make much sense but anyway
a = A()
a.check() # >>> True
# >>> True
# >>> True
a.foo() # ERROR
我看不出是什么导致了这种行为。在我看来,它与python描述符协议有关,所有绑定与未绑定的方法的东西。不知何故,foo.var
属性是可访问的,但不可写。
感谢任何帮助。
P.S。我知道静态函数变量本质上是类变量,在第二种情况下这个装饰器是不必要的,但问题更多的是为了理解Python而不是获得任何有效的解决方案。
答案 0 :(得分:1)
a.foo
不会返回您定义的实际函数;它返回一个绑定的方法,它包装了函数并将self
分配给a
。
https://docs.python.org/3/howto/descriptor.html#functions-and-methods
该指南有点过时,因为未绑定的方法只返回Python 3中的函数。
因此,要访问该函数的属性,您需要通过A.foo
(或a.foo.__func__
)代替a.foo
。这只适用于Python 3.在Python 2中,我认为A.foo.__func__
将起作用。