【问题标题】:Scope inside Python execPython exec 中的作用域
【发布时间】:2012-07-04 18:48:27
【问题描述】:

当在exec 中定义变量/函数时,它似乎转到locals() 而不是globals() 我该如何改变这种行为?仅当您将全局和本地字典传递给exec 时才会发生这种情况。

例子:

exec("""
a = 2

def foo():
    print a

foo()""") in {},{}

当你尝试这个时:

NameError: global name 'a' is not defined

【问题讨论】:

    标签: python scope exec globals locals


    【解决方案1】:

    如果a 不是全局的,则将其设为全局...

    exec("""
    global a
    a = 2
    
    def foo():
        print a
    
    foo()""") in {}, {}
    

    【讨论】:

    • 是的,但是exec 中的代码是由不知道在exec 中的第三方编写的,因此他们认为没有理由使用全局。
    • 那你为什么没有在问题中提到这一点?我以为你是一个初学者(11 个代表),只是不知道 global。
    【解决方案2】:

    乍一看我也觉得很奇怪。但是有了更多的输出,我找到了原因:

    >>> g, l = {}, {}
    >>> print id(g), id(l)
    12311984 12310688
    >>>
    >>> exec '''
    ... a = 2
    ... print 'a' in globals(), 'a' in locals(), id(globals()), id(locals())
    ... def f():
    ...     print 'a' in globals(), 'a' in locals(), id(globals()), id(locals())
    ... f()
    ... ''' in g, l
    False True 12311984 12310688
    False False 12311984 12311264
    

    如http://effbot.org/pyfaq/what-are-the-rules-for-local-and-global-variables-in-python.htm中所说:

    在 Python 中,仅在函数内部引用的变量是隐式全局的。如果一个变量在函数体内的任何地方都被赋予了一个新值,那么它就被认为是一个局部变量。如果一个变量在函数内部被赋予了一个新值,这个变量是隐式局部的,你需要显式地将它声明为全局的。

    所以一种解决方案是对全局变量和本地变量使用相同的字典:

    >>> l = {}
    >>> exec '''
    ... a = 2
    ... def f():
    ...     print a
    ... f()
    ... ''' in l, l
    2
    

    【讨论】:

    • 谢谢!另一个解决方案是只传递全局字典。但很高兴知道原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 2015-03-02
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多