实现python发电机与闭包 [英] implementing python generators with closures

查看:123
本文介绍了实现python发电机与闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何摆脱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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆