python – 具有空本地的exec中的列表解析:NameError
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 具有空本地的exec中的列表解析:NameError,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2756字,纯文字阅读大概需要4分钟。
内容图文
![python – 具有空本地的exec中的列表解析:NameError](/upload/InfoBanner/zyjiaocheng/701/0f9529dc503f4833b93531c0716fff35.jpg)
请考虑以下代码段:
def bar():
return 1
print([bar() for _ in range(5)])
它给出了预期的输出[1,1,1,1,1].
但是,如果我尝试在空环境中执行相同的代码片段(locals和globals都设置为{}),则会给出NameError:
if 'bar' in globals() or 'bar' in locals():
del bar
# make sure we reset settings
exec("""
def bar():
return 1
print([bar() for _ in range(5)])
""", {}, {})
NameError: name 'bar' is not defined
如果我调用exec(如exec(…,{})或exec(…)),它将按预期执行.
为什么?
编辑:
还要考虑以下代码段:
def foo():
def bar():
return 1
print('bar' in globals()) # False
print('bar' in locals()) # True
print(['bar' in locals() for _ in [1]]) # [False]
print([bar() for _ in [1, 2]]) # [1, 1]
就像在我的第一个执行官中一样,我们在列表理解中没有本地人的栏.但是,如果我们尝试调用它,它就可以了!
解决方法:
您的问题的解决方案在于:
In all cases, if the optional parts are omitted, the code is executed in the current scope. If only globals is provided, it must be a dictionary, which will be used for both the global and the local variables. If globals and locals are given, they are used for the global and local variables, respectively. If provided, locals can be any mapping object. Remember that at module level, globals and locals are the same dictionary. If exec gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.
https://docs.python.org/3/library/functions.html#exec
基本上,您的问题是bar在本地范围内定义,仅在本地中定义.因此,这个exec()语句有效:
exec("""
def bar():
return 1
print(bar())
""", {}, {})
但是,列表推导会创建一个新的本地范围,其中未定义条形,因此无法查找.
此行为可以通过以下方式说明:
exec("""
def bar():
return 1
print(bar())
print(locals())
print([locals() for _ in range(1)])
""", {}, {})
返回
1
{'bar': <function bar at 0x108efde18>}
[{'_': 0, '.0': <range_iterator object at 0x108fa8780>}]
编辑
在您的原始示例中,bar的定义可在(模块级别)全局范围中找到.这对应于
Remember that at module level, globals and locals are the same dictionary.
在exec示例中,通过传递两个不同的字典,在globals和locals之间的范围内引入了一个人工拆分.如果你传递相同的一个或只传递全局的一个(这反过来意味着这个将用于全局和本地),你的例子也可以.
至于编辑中引入的示例,这归结为python中的作用域规则.有关详细说明,请阅读:https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces
简而言之,虽然bar不在列表理解的局部范围内,也不在全局范围内,但它属于foo的范围.并且考虑到Python作用域规则,如果在本地作用域中找不到变量,则将在封闭作用域中搜索它,直到达到全局作用域.在您的示例中,foo的范围位于本地范围和全局范围之间,因此在到达搜索结束之前将找到bar.
然而,这仍然与exec示例不同,其中您传入的本地范围不包含列表推导的范围,而是完全与它分开.
关于范围规则的另一个重要解释,包括插图,可以在这里找到:http://sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html
内容总结
以上是互联网集市为您收集整理的python – 具有空本地的exec中的列表解析:NameError全部内容,希望文章能够帮你解决python – 具有空本地的exec中的列表解析:NameError所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。