一个经常被问到的问题是Python中的函数内部是否存在静态变量.有许多答案,例如使用嵌套函数,装饰器等创建包装类.
我找到的最优雅的解决方案之一就是这个,我稍作修改:
def foo():
# see if foo.counter already exists
try: test = foo.counter
# if not, initialize it to whatever
except AttributeError: foo.counter = 0
# do stuff with foo.counter
.....
.....
Run Code Online (Sandbox Code Playgroud)
例:
static.py
def foo(x):
# see if foo.counter already exists
try: test = foo.counter
# if not, initialize it to whatever
except AttributeError: foo.counter = 0
foo.counter += x
print(foo.counter)
for i in range(10):
foo(i)
Run Code Online (Sandbox Code Playgroud)
产量
$ python static.py
0
1
3
6
10
15
21
28
36
45
Run Code Online (Sandbox Code Playgroud)
有什么理由我应该避免这种方法吗?无论如何,它是如何工作的?
它之所以有效,是因为该函数的名称只是本地作用域中的另一个条目,并且该函数是一个像 Python 中其他所有内容一样的对象,并且可以在其上设置任意属性:
def foo():
# The foo function object has already been fully constructed
# by the time we get into our `try`
try: test = foo.counter # Only run when foo is invoked
except AttributeError: foo.counter = 0
foo.counter += 1
if hasattr(foo, 'counter'):
print('Foo has a counter attribute')
else:
# This prints out - we've parsed `foo` but not executed it yet
print('Foo.counter does not exist yet')
# Now, we invoke foo
foo()
if hasattr(foo, 'counter'):
# And from now on (until we remove the attribute)
# this test will always succeed because we've added the counter
# attribute to the function foo.
print('Foo has a counter attribute')
else:
print('Foo.counter does not exist yet') # No longer true
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
558 次 |
| 最近记录: |