加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

exec中的python字典理解使用全局变量而不是本地变量

发布时间:2020-12-20 13:36:18 所属栏目:Python 来源:网络整理
导读:我发现在exec和eval中使用字典理解和其他方法之间存在以下差异.总之,不同之处在于,当使用理解时,变量取自globals参数,但不使用理解的等效代码从locals参数中获取变量. 这可以从Python Software Foundation Windows安装程序的Python 2.7.3中找到. 执行以下代
我发现在exec和eval中使用字典理解和其他方法之间存在以下差异.总之,不同之处在于,当使用理解时,变量取自globals参数,但不使用理解的等效代码从locals参数中获取变量.

这可以从Python Software Foundation Windows安装程序的Python 2.7.3中找到.

执行以下代码时:

locals1 = {"d":{1: 'x',2: 'y',3: 'z'},"test":3}
globals1 = dict(globals().items() + [("d",{1: 'a',2: 'b',3: 'c'}),("test",2)])
exec "new = {key:d[key] for key in d if key != test}" in globals1,locals1
print locals1

输出是:

{'test': 3,'new': {1: 'a',3: 'c'},'d': {1: 'x',3: 'z'}}

请注意,字典(d)和测试值(测试)都取自globals参数.

执行等效代码时:

locals2 = {"d":{1: 'x',"test":3}
globals2 = dict(globals().items() + [("d",2)])
exec "new = d.copy(); new.pop(test)" in globals2,locals2
print locals2

生成此输出:

{'test': 3,'new': {1: 'x',2: 'y'},3: 'z'}}

在这种情况下,字典(d)和测试值(测试)都取自locals参数.

进一步的指示是,如果字典和/或测试值不在globals参数中,即使它们在locals参数中,具有理解的代码的执行将失败,并且变量未找到异常.

请注意,这不是关于使用exec的问题,我有充分的理由使用exec.使用eval可以证明相同的情况.

解决方法

这是完全正确的;字典理解作为函数范围执行.在该范围内未定义的该函数范围中引用的任何变量都被假定为全局变量.

如果要在执行代码中使用显式函数,则会获得相同的效果:

>>> locals3 = {"d":{1: 'x',"test":3}
>>> globals3 = dict(globals().items() + [("d",2)])
>>> exec "def f():n    new = d.copy()n    new.pop(test)n    return newnnew = f()" in globals3,locals3
>>> print locals3
{'test': 3,'f': <function f at 0x106bbcaa0>}

这在Displays for sets and dictionaries部分中有记录:

Note that the comprehension is executed in a separate scope,so names assigned to in the target list don’t “leak” in the enclosing scope.

在Python 2.x中,列表推导没有自己的范围,这在Python 3中已经被改变了.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读