我在寻找Python中的静态值。
我找到了this。
def static_var(varname, value):
def decorate(func):
setattr(func, varname, value)
return func
return decorate
@static_var("counter", 0)
def foo():
foo.counter += 1
print "Counter is %d" % foo.counter
在函数中使用python decorator作为静态变量。
装饰器(static_var)
在返回装饰的(foo.counter)
函数之前初始化静态值(foo)
。
所以我认为它不应该按预期工作,因为每次调用(static_var)
时,装饰器foo.counter
都会初始化foo
。
因此,我认为如果foo()被调用两次,它应该打印1
两次
foo()
foo()
但它打印1
和2
,增加foo.counter
为什么......?
为什么每次调用foo时foo.counter
都没有初始化为0
?
答案 0 :(得分:3)
由于:
def static_var(varname, value):
def decorate(func):
setattr(func, varname, value)
return func
return decorate
@static_var("counter", 0)
def foo():
foo.counter += 1
print "Counter is %d" % foo.counter
相当于:
foo = static_var("counter", 0)(foo)
请注意static_var()
实际上被调用了?现在走过你的装饰师;事实上,用import pdb; pdb.set_trace()
装饰者包装其他功能可能会改变它们或 返回新功能或两者兼而有之。
请参阅:Understanding Python Decorators in 12 easy steps
如果我们在你的装饰者身上留下一些print
(s),请注意会发生什么:
def static_var(varname, value):
print "1"
def decorate(func):
print "2"
setattr(func, varname, value)
return func
print "3"
return decorate
@static_var("counter", 0)
def foo():
foo.counter += 1
print "Counter is %d" % foo.counter
foo()
foo()
输出:
$ python foo.py
1
3
2
Counter is 1
Counter is 2
正如我上面所说;首先调用
static_var("counter", 0)
; 然后调用返回(返回函数)foo
因为它是第一个设置初始“计数器”的参数 返回相同的参数(函数foo
)。
答案 1 :(得分:2)
“foo.counter每次调用foo时都会初始化为0?”
简答:不,foo.counter
仅在调用static_var
时设为0。
我想也许你对装饰器和函数装饰器的创建很少感到困惑。
@decorator
def func():
pass
只是
的语法糖func = decorator(func)
有了这个,我们就知道您之前的代码等于:
def foo():
foo.counter += 1
print "Counter is %d" % foo.counter
foo = static_val(foo, "counter", 0)
然后,当您致电foo()
时,您正在调用新的foo
函数,而不是static_val
,其中counter
属性将设置为0。
答案 2 :(得分:1)
您看到的行为是正确的。装饰器仅在声明时执行一次,而不是在每次调用装饰函数时执行。因此foo.counter
仅初始化为0一次。
想想静态变量是什么。通常(例如在C中)它是函数的局部变量,它在函数调用期间持续存在。通过使用名为static_var
的装饰器来实现相同的效果,因此每次调用foo.counter
时foo()
递增都是有意义的,而不是重置。