我正在尝试在Python 2.7中创建一个示例程序,它在两个函数之间保存/共享状态。 你调用一个函数,下次你调用一个函数时,它应该记住以前的值。这是我目前的代码:
def stuff():
global x
x = 100
def f():
global x
x = x * 2
return x
def g():
global x
x = x * 4
return x
return (f, g)
a,b = stuff()
print(a());
此代码有效,但问题是x
不能被视为stuff()
的范围之外的全局变量 ...(这就是重点首先在stuff()
内嵌入x)。那么,x
是全局的,还是stuff()
的本地?
答案 0 :(得分:2)
在Python 3.x中,您可以使用nonlocal
语句:
def stuff():
x = 100
def f():
nonlocal x
x = x * 2
return x
def g():
nonlocal x
x = x * 4
return x
return f, g
>>> a, b = stuff()
>>> a()
200
>>> b()
800
>>> a()
1600
答案 1 :(得分:2)
如果你需要支持python 2.X,@ georgek的答案是最好的,但是很多人都没有意识到你可以为函数添加属性。一个常见的习惯用法是使用单个元素的列表来保存变量。
def stuff():
x = [100]
def g():
x[0] = x[0]*2
return x[0]
def h():
x[0] = x[0]*4
return x[0]
return (g,h)
a, b = stuff()
print(a())
这是有效的,因为你从不在内部作用域中分配x本身,所以它不会重新绑定变量并遮蔽闭包。
答案 2 :(得分:1)
最简单,最简单的解决方案,使用课程:
class stuff(object):
x = 100
def f(self):
self.x = self.x * 2
return self.x
def g(self):
self.x = self.x * 4
return self.x
结果:
>>> s = stuff()
>>> s.f()
200
>>> s.g()
800
您希望阻止人们从功能外部访问x
。你在Python中这样做的方法是在它前面添加一个下划线:
class stuff(object):
_x = 100
def f(self):
self._x = self._x * 2
return self._x
def g(self):
self._x = self._x * 4
return self._x
这告诉其他Python程序员它是内部的,而不是访问它,除了他们自己的风险。你似乎想要阻止这一点,但你不能。您甚至可以在Python 3非本地示例中访问闭包:
def stuff():
x = 100
def f():
nonlocal x
x = x * 2
return x
return f
>>> a = stuff()
>>> a()
200
>>> a()
400
>>> a.__closure__[0].cell_contents
400
所以你并没有阻止任何人摆弄它,你只是让它变得晦涩难懂。而且更有可能失败。因此,你最终会让每个参与者都变得更加困难。
答案 3 :(得分:0)
您可以使用没有全局的功能:
>>> def f():
... f.x = 100
... def g():
... f.x = f.x * 2
... return f.x
... def h():
... f.x = f.x * 4
... return f.x
... return (g, h)
...
>>> a, b = f()
>>> a()
200
>>> b()
800
>>> a()
1600
>>>