Python 2 vs.3中的评估范围 [英] Eval scope in Python 2 vs. 3

查看:71
本文介绍了Python 2 vs.3中的评估范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Python 3中遇到了奇怪的eval行为-在列表理解中调用eval时未获取局部变量.

I came across bizarre eval behavior in Python 3 - local variables aren't picked up when eval is called in a list comprehension.

def apply_op():
    x, y, z = [0.5, 0.25, 0.75]
    op = "x,y,z"
    return [eval(o) for o in op.split(",")]
print(apply_op())

Python 3中的错误:

It errors in Python 3:

▶ python --version
Python 3.4.3
▶ python eval.py
Traceback (most recent call last):
  File "eval.py", line 7, in <module>
    print(apply_op())
  File "eval.py", line 5, in apply_op
    return [eval(o) % 1 for o in op.split(",")]
  File "eval.py", line 5, in <listcomp>
    return [eval(o) % 1 for o in op.split(",")]
  File "<string>", line 1, in <module>
NameError: name 'x' is not defined

它在Python 2中正常工作

And it works fine in Python 2:

▶ python --version
Python 2.7.8
▶ python eval.py
[0.5, 0.25, 0.75]

将其移出列表理解范围即可解决此问题.

Moving it outside of the list comprehension removes the problem.

def apply_op():
    x, y, z = [0.5, 0.25, 0.75]
    return [eval("x"), eval("y"), eval("z")]

这是预期的行为,还是错误?

Is this intended behavior, or is it a bug?

推荐答案

错误跟踪器中有一个 closed 问题,该问题是:

There is a closed issue in the bug tracker for this: Issue 5242.

此错误的解决方法是无法解决.

该期杂志的一些评论如下:

Some comments from the Issue read:

这是预料之中的,并且不会轻易解决.原因是清单3.x中的理解使用在幕后"的函数名称空间(在2.x中,它们的实现就像一个简单的for循环).因为内部功能需要知道从什么封闭的名称空间获得什么名称,这些名称eval()中引用的引用不能来自封闭函数.他们一定要么是本地人,要么是全球人.

This is expected, and won't easily fix. The reason is that list comprehensions in 3.x use a function namespace "under the hood" (in 2.x, they were implemented like a simple for loop). Because inner functions need to know what names to get from what enclosing namespace, the names referenced in eval() can't come from enclosing functions. They must either be locals or globals.

eval()可能已经是黑客,无需添加其他黑客使它工作.最好摆脱eval()并找到一个更好的方法做自己想做的方式.

eval() is probably already an hack, there's no need to add another hack to make it work. It's better to just get rid of eval() and find a better way to do what you want to do.

这篇关于Python 2 vs.3中的评估范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆