繁体   English   中英

Python:如何在函数的本地范围内运行 eval()

[英]Python: How can I run eval() in the local scope of a function

我尝试在函数的局部范围内使用 eval()。 然而,它总是在全局范围内进行评估。

自包含示例:

1-此代码有效:

var1 = 1
var2 = 2
var3 = 3    
myDict = dict((name, eval(name)) for name in ["var1",
                                              "var2",
                                              "var3"])
print(myDict["var1"])

2- 为lvar1抛出NameError

def test1():
   lvar1 = 1
   lvar2 = 2
   lvar3 = 3
   myDict = dict((name, eval(name)) for name in ["lvar1",
                                                 "lvar2",
                                                 "lvar3"])
   print(myDict["lvar1"])

3- 与 2 相同的结果。

def test2():
    lvar1 = 1
    lvar2 = 2
    lvar3 = 3
    myDict = dict((name, eval(name), locals()) for name in ["lvar1",
                                                            "lvar2",
                                                            "lvar3"])
    print(myDict["lvar1"])

保存locals() (或vars() )调用的结果以返回函数的局部作用域。 否则,生成器表达式中的locals()将返回 gen-expr 的局部作用域。

def test3():
    lvar1 = 1
    lvar2 = 2
    lvar3 = 3
    scope = locals()
    myDict = dict((name, eval(name, scope)) for name in [
                  "lvar1", "lvar2", "lvar3"])
    print(myDict["lvar1"])

顺便说一句,您不需要明确的理解来构建该字典:

# copy() avoids quirky, unexpected updates if something else (like a debugger)
# accesses locals() or f_locals
myDict = locals().copy()  # or vars().copy()

首先,阅读此内容很重要:

表达式参数被解析和评估为 Python 表达式(从技术上讲,条件列表),使用 globals 和 locals 字典作为全局和本地命名空间。 如果 globals 字典存在并且缺少'__builtins__' ,则在解析表达式之前将当前全局变量复制到全局变量中。 这意味着表达式通常可以完全访问标准__builtin__模块,并且会传播受限环境。 如果省略 locals 字典,则默认为 globals 字典。 如果两个字典都被省略,则表达式在调用eval()的环境中执行。 返回值是计算表达式的结果。

首先要注意的是,生成器表达式有自己的范围(对于字典理解也是如此),因此它有自己的locals()字典。

  1. 这是有效的,因为在全局范围内globals()locals() dict 都指向同一个字典,因此 dict 构造函数可以访问这些变量。

  2. 这里我们再次调用没有globals()locals() dict 的eval()因此它最终使用全局范围和它自己的本地范围(这是空的),并且在任何这些范围中都没有这样的变量可用。

  3. 请记住,生成器有自己的作用域,因此在此处调用locals()几乎没有任何区别,它是一个空字典。

解决方案:

def test1():
   lvar1 = 1
   lvar2 = 2
   lvar3 = 3
   test1_locals = locals()
   myDict = dict((name, eval(name, test1_locals)) for name in ["lvar1",
                                                 "lvar2",
                                                 "lvar3"])
   print myDict
   print(myDict["lvar1"])

这是有效的,因为我们在一个变量中捕获了 test1 的locals() ,然后在字典理解中使用了该字典,因此它现在可以访问这些变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM