实现python发电机与闭包 [英] implementing python generators with closures
问题描述
如何摆脱fib_gen2中的全局变量?我不想根据此 gist 使用原生生成器或类,这是一个学术练习,但我
how can i get rid of the globals in fib_gen2? I don't want to use native generators or classes per this gist, this is an academic exercise, though I am interested improvements in any of the implementations.
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
语句:
In Python 3.x, you can use the 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中,您需要使用一些hack:
In Python 2.x, you'll need to use some hack:
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
的原因。
This unsatisfactory situation was the very reason for the introduction of nonlocal
in Python 3.x.
Python没有变量声明,因此它必须找出每个变量本身的范围。它通过一个简单的规则这样做:如果在函数中有一个名字的赋值,这个名字是该函数的局部变量,除非它被显式声明为 global
或 nonlocal
。在第二个示例中,没有对名称 ab
的分配 - 列表已修改,但名称未重新分配。因此范围是包围函数。
Python has no variable declarations, so it has to figure out the scope of each variable itself. It does so by a simple rule: If there is an assignment to a name inside a function, this name is local to that function -- except it is explicitly declared global
or nonlocal
. In the second example, there is no assignment to the name ab
-- the list is modified, but the name is not reassigned. Thus the scope is the enclosing function.
这篇关于实现python发电机与闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!