gpt4 book ai didi

python - 字典理解中无法访问函数参数

转载 作者:太空狗 更新时间:2023-10-30 02:46:50 25 4
gpt4 key购买 nike

为什么在字典理解中使用 eval 访问函数参数会失败?

ARGS1 = ('a1', 'b1')
def foo1(a1, b1):
return {arg:eval(arg) for arg in ARGS1}
print foo1("A1", "B1") # NameError: name 'a1' is not defined

在列表推导中同样的事情是可以的:

ARGS2 = ('a2', 'b2')
def foo2(a2, b2):
return [eval(arg) for arg in ARGS2]
print foo2("A2", "B2") # OK, print: ['A2', 'B2']

它在没有函数的情况下也能正常工作:

ARGS3 = ('a3', 'b3')
a3, b3 = ("A3", "B3")
print {arg:eval(arg) for arg in ARGS3} # OK, print: ['A3', 'B3']

或者如果定义了全局变量:

ARGS4 = ('a4', 'b4')
a4, b4 = ("A4", "B4")
def foo4():
return [eval(arg) for arg in ARGS4]
print foo4() # OK, print: ['A4', 'B4']

这看起来确实像一个错误,但也许我在这里遗漏了一些东西。

(编辑以包括无功能和带全局的示例)

最佳答案

字典理解在一个新的范围内执行,就像一个函数。

因此,局部表达式仅限于只是在循环中命名的那些,在本例中为arg考虑父函数局部变量,因为闭包在编译时绑定(bind)。 eval() 引用的名称不能使用闭包。

以下不起作用:

>>> ARGS = ('a', 'b')
>>> def bar(a, b):
... def foo():
... for arg in ARGS:
... eval(arg)
... return foo
...
>>> print bar("A", "B")()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in foo
File "<string>", line 1, in <module>
NameError: name 'a' is not defined

名称 ab 对内部 foo 函数不可用,除非编译器确定该函数确实需要访问它们:

>>> def bar2(a, b):
... def foo():
... a, b
... for arg in ARGS:
... eval(arg)
... return foo
...
>>> print bar2("A", "B")()
None
>>> print bar2("A", "B").func_closure
(<cell at 0x1051bac20: str object at 0x104613328>, <cell at 0x1051bacc8: str object at 0x1045971e8>)
>>> print bar2("A", "B").__code__.co_freevars
('a', 'b')

这里,行 a, b 只能引用父作用域局部变量(它们没有分配给 foo() 本身),所以编译器有为这些创建了闭包,并且这些名称在 foo() 中变得可用。

Python 2 中的列表推导式没有自己的命名空间,Python 3 中纠正了一个遗漏,并且没有扩展到 dict 和 set 推导式。参见 Python list comprehension rebind names even after scope of comprehension. Is this right?

关于python - 字典理解中无法访问函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18664274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com