Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有自定义dict的Eval()不';我不在CPython工作_Python_Cpython - Fatal编程技术网

带有自定义dict的Eval()不';我不在CPython工作

带有自定义dict的Eval()不';我不在CPython工作,python,cpython,Python,Cpython,我正在尝试使用自定义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)

我正在尝试使用自定义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
12
['fooofooofooo','barbarbarbar']
{'foo':'fooofoo','bar':'barbarbar'}
12
['fooofooofooo','barbarbarbar']
回溯(最近一次呼叫最后一次):
文件“”,第22行,在
文件“”,第15行,使用命令运行
文件“”,第1行,在
文件“”,第1行,在
NameError:未定义全局名称“y”
但是当它与PyPy2.7一起运行时,它工作得很好。它在任何Python3中都可以正常工作


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

CPython经常走捷径。CPython 2.7中的dict理解要求dict完全是一个
dict
,而不是其子类。它不需要调用您被覆盖的
\uuu getitem\uu
方法;它直接指向dict.uuu getitem_uuu,当然看不到名为
y
的条目


我不确定这是否是未定义的行为,但在python 3中更改的事实意味着这是一个bug。

如果有人感兴趣,可以将一个子类dict传递给
FunctionType
构造函数。这不可能是对的,因为前两条语句按预期工作(并且确实调用被重写的
\uu getitem\uu
).正如问题中所指出的,只有听写理解失败。@ekhumoro我没有遵循你的逻辑。听写理解和其他测试表达式之间显然有一些细微的差别。为什么不能以这种细微的差别对待听写呢?@ekhumoro第一条语句在模块范围内执行(eval),在Python2中,第二个也在模块scope()中执行。dict comprehension在2和3中创建了一个新的作用域缩短变量查找并直接使用
dict.\uuuu getitem\uuuuuuu
。这当然可以在调用
\uuu getitem\uuuuuuuu
时进行检查,使子类打印出来。@ekhumaro啊,我想我的答案有点不清楚……我会重新表述一下。我意识到这是玩具演示代码,但有什么原因吗您不能在初始化过程中将
y
作为一项添加到dict中?有些变量可能是从磁盘动态加载的,它不知道在给定的评估中会使用哪些变量。