有人可以解释这个错误吗? DictTest.py的内容如下。如果我将此代码复制(%粘贴)到ipython终端,则测试通过。如果打电话
>>> %run DictTest.py -m
测试失败,
name 'keys' is not defined
它所抱怨的“键”是字典理解中的“键”部分。我在linux上使用3.4.1 | Anaconda 2.1.0(64位)。
#!/usr/bin/python3.4
import unittest
class DictTest(unittest.TestCase):
def test_dict_comprehension(self):
code = """
d = {'a':1, 'b':2, 'c':3, 'd':4}
keys = ['a', 'd']
items = d.items()
nd = {k: v for k, v in items if k in keys}
print('>>>' + str(nd))
"""
try:
exec(code)
except Exception as e:
self.assertTrue(False, "Exec ERROR>>> %s" % e)
def main():
dt = DictTest()
dt.test_dict_comprehension()
if __name__ =='__main__':main()
答案 0 :(得分:1)
答案是(主要)在exec,赋值语句和理解的文档中。\
exec:exec(s)相当于exec(s,globals(),locals())。在模块范围(case1),locals是globals()。在函数范围(case2)中,它们是两个不同的对象。 “如果exec获得两个独立的对象作为全局变量和局部变量,则代码将被执行,就像它嵌入在类定义中一样。”以下是关于“密钥”无法识别的相同错误。
class C:
d = {'a':1, 'b':2, 'c':3, 'd':4}
keys = ['a', 'd']
items = d.items()
nd = {k: v for k, v in items if k in keys}
print('>>>' + str(nd))
=:name = value
将name绑定到本地命名空间中的value,该命名空间可能与全局命名空间相同或不同。
{comprehension}:在3.x中,在单独的上下文中评估一个理解(第一个for子句的来源除外 - 没有很好地记录)。因此,立即评估项目,同时在新的上下文中评估“密钥”,其中本地只有“k”和“v”的绑定(这就是“k”被评估的原因)。对于案例2,'keys'也不在全局变量中,并且引发异常。
此代码的解决方案:
d = {}
...
exec(code, d, d)
其他用途可能需要对d进行额外初始化。