Python闭包函数失去外部变量访问 [英] Python closure function losing outer variable access

查看:334
本文介绍了Python闭包函数失去外部变量访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚学习了python @ decorator,很酷,但很快我发现我修改的代码出现了奇怪的问题。

  def with_wrapper(param1):
def dummy_wrapper(fn):
print param1
param1 ='new'
fn(param1)
return dummy_wrapper

def dummy():
@with_wrapper('param1')
def implementation(param2):
print param2

dummy()

我调试它,它抛出异常在打印param1

  UnboundLocalError:赋值前引用的局部变量'param1'

删除 param1 ='new'这行,没有对外部变量的任何修改操作(链接到新对象),此例程可能工作。



这是否意味着我只做一个外部范围变量的副本,然后进行修改?






谢谢Delnan,它是关键。
从这里可能回答:


类似的代码如下:

  def e(a):
def f():
print a
a ='1'
f be('2')

这也似乎是前面讨厌的全局变量:

  a ='1'
def b():
#global a
打印a
a = '2'
b()

这是通过添加 >符号。
但是对于闭包,没有找到这样的符号。
感谢unutbu,Python 3给了我们非本地



我知道从上面直接访问外部变量是只读的。

解决方案

当Python解析时一个函数,它注意每当它找到一个赋值的左侧使用的变量,如

  param1 = new'

它假设所有这些变量都是函数的本地变量。
当您在此作业前加上

  print param1 
pre>

发生错误,因为Python在执行print语句时没有此局部变量的值。






在Python3中,你可以声明 param1 是非本地的:

  def with_wrapper(param1):
def dummy_wrapper(fn):
nonlocal param1
print param1
param1 = new'
fn(param1)
return dummy_wrapper






在Python2中,你必须使用一个技巧,例如在列表(或其他可变对象)中传递param1:

 code> def with_wrapper(param1_list):
def dummy_wrapper(fn):
print param1_list [0]
param1_list [0] ='new'#mutate列表中的值
fn(param1_list [0])
return dummy_wrapper

def dummy():
@with_wrapper(['param1'])#&传递一个列表
def implementation(param2):
print param2


I just learned python @ decorator, it's cool, but soon I found my modified code coming out weird problems.

def with_wrapper(param1):
    def dummy_wrapper(fn):
        print param1
        param1 = 'new'
        fn(param1)
    return dummy_wrapper

def dummy():
    @with_wrapper('param1')
    def implementation(param2):
        print param2

dummy()

I debug it, it throws out exception at print param1

UnboundLocalError: local variable 'param1' referenced before assignment

If I remove param1 = 'new' this line, without any modify operation (link to new object) on variables from outer scope, this routine might working.

Is it meaning I only have made one copy of outer scope variables, then make modification?


Thanks Delnan, it's essential to closure. Likely answer from here: What limitations have closures in Python compared to language X closures?

Similar code as:

def e(a):
    def f():
        print a
        a = '1'
    f()
e('2')

And also this seems previous annoying global variable:

a = '1'
def b():
    #global a
    print a
    a = '2'
b()

This is fixed by add global symbol. But for closure, no such symbol found. Thanks unutbu, Python 3 gave us nonlocal.

I know from above directly accessing to outer variable is read-only. but it's kind of uncomfortable to see preceded reading variable(print var) is also affected.

解决方案

When Python parses a function, it notes whenever it finds a variable used on the left-hand side of an assignment, such as

param1 = 'new'

It assumes that all such variables are local to the function. So when you precede this assignment with

print param1

an error occurs because Python does not have a value for this local variable at the time the print statement is executed.


In Python3 you can fix this by declaring that param1 is nonlocal:

def with_wrapper(param1):
    def dummy_wrapper(fn):
        nonlocal param1
        print param1
        param1 = 'new'
        fn(param1)
    return dummy_wrapper


In Python2 you have to resort to a trick, such as passing param1 inside a list (or some other mutable object):

def with_wrapper(param1_list):
    def dummy_wrapper(fn):
        print param1_list[0]
        param1_list[0] = 'new'   # mutate the value inside the list
        fn(param1_list[0])
    return dummy_wrapper

def dummy():
    @with_wrapper(['param1'])   # <--- Note we pass a list here
    def implementation(param2):
        print param2

这篇关于Python闭包函数失去外部变量访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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