我尝试在函数的局部作用域中使用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表达式的本地作用域。
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表达式进行解析和计算(从技术上讲,是一个条件列表)使用全局和局部字典作为全局和本地命名空间。如果全局字典存在并且缺少
‘__builtins__’
,则复制当前全局变量在解析表达式之前转换为全局变量。这意味着表达式通常可以完全访问标准__builtin__
模块传播受限环境。如果本地字典省略它默认为globals字典。如果两个词典则表达式在以下环境中执行:调用CCD_ 8。返回值是评估的结果表达式`。
首先需要注意的是,生成器表达式有自己的作用域(对于dict理解也是如此),因此它有自己的locals()
字典。
-
这是因为在全局范围内,
globals()
和locals()
dict都指向同一个字典,因此dict构造函数可以访问这些变量。 -
在这里,我们再次调用没有
globals()
和locals()
dict的eval()
,因此它最终使用全局作用域和它自己的本地作用域(它是空的),并且在这些作用域中都没有可用的此类变量。 -
记住生成器有自己的作用域,所以在这里调用
locals()
几乎没有什么区别,它是一个空的dict
解决方案:
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()
,然后在字典理解中使用了该字典,所以它现在可以访问这些变量。