Python:dict comprehension and eval function variable scope



代码 1:for 循环

def foo():
one = '1'
two = '2'
three = '3'
d = {}
for name in ('one', 'two', 'three'):
d[name] = eval(name)
print(d)
foo()

输出:

{'一': '1', '二': '

2', '三': '3'}

代码2:字典理解

def foo():
one = '1'
two = '2'
three = '3'
print({name: eval(name) for name in ('one', 'two', 'three')})
foo()

输出:

名称

错误:未定义名称"一">

代码3:添加全局关键字

def foo():
global one, two, three  # why?
one = '1'
two = '2'
three = '3'
print({name: eval(name) for name in ('one', 'two', 'three')})
foo()

输出:

{'一': '1', '二': '

2', '三': '3'}

字典推导和生成器推导创建自己的局部范围。根据闭包的定义(或者这里不是闭包(,但为什么代码 2 无法访问外部函数foo的变量one[,two,three]?但是,Code 3 可以通过将变量one[,two,three]设置为全局来成功创建字典吗?

那么是因为eval函数和字典理解有不同的范围吗?

希望有人帮助我,我会感激不尽!

要了解发生了什么,请尝试以下操作:

def foo():
global one
one = '1'
two = '2'
print({'locals, global': (locals(), globals()) for _ in range(1)})
foo()

输出

{'locals, global': ({'_': 0, '.0': <range_iterator object at ...>},
{'__name__': '__main__', '__package__': None, ..., 'one': '1'})}

内置eval(expression)eval(expression[, globals[, locals]])的快捷方式。

正如您在前面的输出中看到的,locals()不是函数的本地符号表,因为列表/字典推导式有自己的作用域(例如,请参阅 https://bugs.python.org/msg348274(。

要获得预期的输出,您只需将函数的本地符号表传递给eval

def bar():
one = '1'
two = '2'
three = '3'
func_locals = locals() # bind the locals() here
print({name: eval(name, globals(), func_locals) for name in ('one', 'two', 'three')})
bar()

输出

{'one': '1', 'two': '2', 'three': '3'}

相关内容

最新更新