带有自定义dict的Eval()在CPython中不起作用

2024-10-08 18:30:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用自定义dict作为全局变量运行一些表达式。你知道吗

class Namespace(dict):
    def __getitem__(self, key):
        if key == "y":
            return 10
        else:
            return super(Namespace, self).__getitem__(key)

def run_with_dict(d):
    print(eval("x + y", d))
    print(eval("[ (p * y) for p in ['foo', 'bar'] ]", d))
    print(eval("{ p: (p * y) for p in ['foo', 'bar'] }", d))

custom = Namespace()
custom["x"] = 2
regular = {"x": 2, "y": 10}

run_with_dict(regular)
run_with_dict(custom)

在CPython 2.7中运行时,仅在地图上失败:

12
['foofoofoofoofoofoofoofoofoofoo', 'barbarbarbarbarbarbarbarbarbar']
{'foo': 'foofoofoofoofoofoofoofoofoofoo', 'bar': 'barbarbarbarbarbarbarbarbarbar'}
12
['foofoofoofoofoofoofoofoofoofoo', 'barbarbarbarbarbarbarbarbarbar']
Traceback (most recent call last):
  File "<stdin>", line 22, in <module>
  File "<stdin>", line 15, in run_with_dict
  File "<string>", line 1, in <module>
  File "<string>", line 1, in <dictcomp>
NameError: global name 'y' is not defined

但是,当它与pypy2.7一起运行时,它工作得很好。它在任何python3中都可以正常工作。你知道吗

什么样的实现差异可以解释这一点?这是cpython2.7中的bug还是未定义的行为?我能做些什么使它在两种实现中都能工作吗?你知道吗


Tags: keyruninfoowithcustomevalline
1条回答
网友
1楼 · 发布于 2024-10-08 18:30:12

CPython经常走捷径。cpython2.7中的dict理解期望dict是确切的adict,而不是其子类。它不需要调用重写的__getitem__方法;它直接指向dict.__getitem__,当然,它看不到名为y的条目。你知道吗

我不确定这是否是未定义的行为,但在python3中更改的事实意味着这是一个bug。你知道吗

相关问题 更多 >

    热门问题