如何在Python中实现Javascript闭包?

时间:2014-11-20 18:04:32

标签: python python-2.7

我正在尝试在Python 2.7中实现Javascript闭包。

请考虑以下代码:

var = {'upper_scope':None}

def f1():
    print var

def f2():
    var = {'upper_scope': var}

第一个功能正常。第二行在第一行失败:

UnboundLocalError: local variable 'var' referenced before assignment. 

我想从上部范围读取var的值,并将其放在名为var的本地字典中。

3 个答案:

答案 0 :(得分:2)

它在f2()中不起作用,因为您在本地覆盖var的全局定义。 如果你在f2()中重命名var,它将起作用:

def f2():
   other_var = {'upper_scope': var}

或者,您可以将其定义为全局,但是var的值的更改也将应用于全局变量,如下所示:

def f2():
   global var
   var = {'upper_scope': var}

话虽如此,将变量作为参数传递给函数总是一种更好的方法,除非你真的需要在几个地方和/或需要改变它的值。

答案 1 :(得分:1)

这可能是这样做的唯一方法。我在我的JavaScript到Python转换器中使用了这个方法,它确实起到了作用。

var = {'upper_scope':None}
def first(var=var):
    var = {'upper_scope': var}
    def second(var=var):
        var = {'upper_scope': var } 
        def third(var=var):
             var = ...

现在每个函数都“记住”它的上限范围 - 它存储了一个默认参数。另请注意,该函数在调用(var = {'upper_scope': var})时会自动创建局部范围。

答案 2 :(得分:0)

python3语法中有nonlocal statement,它是根据您的要求发明的:access to names in outer scope

对于函数嵌套中的访问全局变量,你可以做这样的事情(在python2和python3中都有效):

var = {'upper_scope':None}
def first():
    global var
    var = {'upper_scope': var}
    def second():
        global var
        var = {'upper_scope': var } 
        def third():
            global var
            var = ...

在所有这些函数中,只存在变量var的一个示例 - 全局变量{{1}}。 因此,内部范围的每个变化都将在更高层次上提供,反之亦然。