我怎样才能去掉 fib_gen2 中的全局变量?我不想根据此 gist 使用 native 生成器或类,这是一个学术练习,尽管我对任何实现的改进感兴趣。
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)
请您参考如下方法:
在 Python 3.x 中,您可以使用 nonlocal statement :
def fib_gen2():
a = b = 1
def next():
nonlocal a, b
a, b = b, a + b
return b - a
return next
在 Python 2.x 中,您需要使用一些技巧:
def fib_gen2():
ab = [1, 1]
def next():
ab[:] = ab[1], ab[0] + ab[1]
return ab[1] - ab[0]
return next
这种不尽如人意的情况正是在 Python 3.x 中引入 nonlocal 的原因。
Python 没有变量声明,所以它必须自己弄清楚每个变量的作用域。它通过一个简单的规则来做到这一点:如果函数内部有一个名称赋值,则该名称是该函数的本地名称——除非明确声明为 global 或 nonlocal。在第二个示例中,名称 ab 没有赋值——列表已修改,但名称未重新赋值。因此范围是封闭函数。
