在评估生成器时,eval无法检测到迭代变量

时间:2017-07-20 19:58:19

标签: python python-3.x generator

请考虑以下代码:

print([a for a in [0] if eval("a in [0]")])
b = 0
print([b if eval("True in (x == b for x in [0])") else ''])
print([a for a in [0] if eval("True in (x == a for x in [0])")])

这个输出是:

[0]
[0]
Traceback (most recent call last):
  File "…", line 4, in <module>
    print([a for a in [0] if eval("False in (x == a for x in [0])")])
  File "…", line 4, in <listcomp>
    print([a for a in [0] if eval("False in (x == a for x in [0])")])
  File "<string>", line 1, in <module>
  File "<string>", line 1, in <genexpr>
NameError: name 'a' is not defined

第一个eval在普通eval中使用迭代器a,它可以工作。

第二个eval在评估生成器时使用静态变量b,并且它可以工作。

第三个eval结合了两个想法 - 它在评估生成器时使用迭代器变量,并且无法检测变量并引发错误。为什么会这样?

1 个答案:

答案 0 :(得分:3)

  • (x == a for x in [0])这样的genexp创建了自己的范围。
  • 列表推导也是如此,至少在Python 3中是这样。
  • eval内的嵌套作用域未看到eval使用的本地变量。

这意味着在这一行:

print([a for a in [0] if eval("True in (x == a for x in [0])")])

a内的eval查找发生在嵌套范围内,因此它不会从a范围的局部变量中看到eval变量发生。