exec不从闭包中接收变量 [英] exec doesn't pick up variables from closure

查看:142
本文介绍了exec不从闭包中接收变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇为什么下面的代码引起了 NameError

 >>>> s =
... foo = [1,2,3]
... def bar():
... return foo [1]
。 ..
>>>> namespace = {}
>>>> exec(s,{'__builtins__':None},命名空间)
>>> print namespace
{'foo':[1,2,3],'bar':< function bar at 0x7f79871bd0c8>}
>>命名空间['bar']()

在正常解释器级别, c> foo 在 bar.func_globals bar.func_closure 我想我想知道为什么命名空间['bar'] 不把 foo func_closure ...

解决方案

原来,答案一直在< a href =http://docs.python.org/2/reference/simple_stmts.html#the-exec-statement =nofollow>文档:


如果两个单独的对象被给定为全局变量和局部变量,代码将被执行,就好像嵌入在类定义中一样。


因为我传入全局 locals

  class Foo(object):
foo = [1,2,3 ]
@staticmethod
def bar():
return foo [1]


$ b



对于任何对解决方法感兴趣的用户,您可以注入命名空间回到命名空间['bar']。func_globals 1 受此启发):

 code>>>>> namespace ['bar']。func_globals.update(namespace)
>>> namespace ['bar']()
2


$ b

1 这将是 namespace ['bar'] .__ globals __。update on python3.x


I'm a little curious why the following code raises a NameError.

>>> s = """
... foo = [1,2,3]
... def bar():
...    return foo[1]
... """
>>> namespace = {}
>>> exec(s, {'__builtins__': None}, namespace)
>>> print namespace
{'foo': [1, 2, 3], 'bar': <function bar at 0x7f79871bd0c8>}
>>> namespace['bar']()

At the normal interpreter level, we can find foo in bar.func_globals or bar.func_closure if in a function. I guess I'm wondering why namespace['bar'] doesn't put foo in func_closure ...

解决方案

It turns out that the answer was there all along in the docs:

If two separate objects are given as globals and locals, the code will be executed as if it were embedded in a class definition.

Since I'm passing in both globals and locals, it executes as if it were in a class.

class Foo(object):
    foo = [1,2,3]
    @staticmethod
    def bar():
       return foo[1]

not surprisingly doesn't work either :).

For anyone interested in a workaround, you can inject namespace back into namespace['bar'].func_globals1 (inspired by this):

>>> namespace['bar'].func_globals.update(namespace)
>>> namespace['bar']()
2

Nice.

1It would be namespace['bar'].__globals__.update on python3.x

这篇关于exec不从闭包中接收变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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