Dus*_*etz 1 python lambda closures
我如何摆脱fib_gen2中的全局变量?我不想按照这个要点使用本机生成器或类,这是一个学术练习,尽管我对任何实现都有兴趣改进.
def ftake(fnext, last):
return [fnext() for _ in xrange(last)]
def fib_gen2():
global a; a = 1
global b; b = 1
def next():
global a; global b;
r = a
a, b = b, a + b
return r
return next
assert [1,1,2,3,5] == ftake(fib_gen2(), 5)
Run Code Online (Sandbox Code Playgroud)
在Python 3.x中,您可以使用以下nonlocal
语句:
def fib_gen2():
a = b = 1
def next():
nonlocal a, b
a, b = b, a + b
return b - a
return next
Run Code Online (Sandbox Code Playgroud)
在Python 2.x中,您需要使用一些hack:
def fib_gen2():
ab = [1, 1]
def next():
ab[:] = ab[1], ab[0] + ab[1]
return ab[1] - ab[0]
return next
Run Code Online (Sandbox Code Playgroud)
这种令人不满意的情况是nonlocal
在Python 3.x中引入的原因.
Python没有变量声明,因此必须弄清楚每个变量本身的范围.它通过一个简单的规则:如果有一个分配给一个函数内部的名称,这个名称是局部的功能-除了它是显式声明的global
或nonlocal
.在第二个示例中,没有对名称的赋值ab
- 列表已修改,但名称未重新分配.因此范围是封闭功能.