栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

exec中具有空本地变量的列表理解:NameError

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

exec中具有空本地变量的列表理解:NameError

解决问题的方法就在这里:

在所有情况下,如果省略了可选部分,则代码将在当前范围内执行。 如果仅提供全局变量,则必须为字典,该字典将用于全局变量和局部变量。
如果给出了全局变量和局部变量,则它们分别用于全局变量和局部变量。
如果提供的话,本地变量可以是任何映射对象。
请记住,在模块级别,全局变量和局部变量是相同的字典。 如果exec获得两个单独的对象作为全局对象和局部对象,则代码将像嵌入在类定义中一样执行。

https://docs.python.org/3/library/functions.html#exec

基本上,您的问题是bar的定义

locals
仅在的范围内
locals
。因此,此
exec()
语句有效:

exec("""def bar():    return 1print(bar())""", {}, {})

但是,列表理解会创建一个新的本地范围,该范围

bar
未定义,因此无法查找。

此行为可以用以下方式说明:

exec("""def bar():    return 1print(bar())print(locals())print([locals() for _ in range(1)])""", {}, {})

哪个返回

1{'bar': <function bar at 0x108efde18>}[{'_': 0, '.0': <range_iterator object at 0x108fa8780>}]

编辑

在您的原始示例中,的定义

bar
位于(模块级别)全局范围内。这对应于

请记住,在模块级别,全局变量和局部变量是相同的字典。

exec
示例中,您通过传递两个不同的字典在全局变量和局部变量之间引入了一个人为的范围划分。如果您传递相同的一个或仅传递一个全局变量(这反过来意味着该变量将用于
globals
locals
),那么您的示例也将起作用。

至于在编辑中引入的示例,这可以归结为python中的作用域规则。有关详细说明,请阅读:https : //docs.python.org/3/tutorial/classes.html#python-
scopes-and-namespaces

简而言之,虽然

bar
不在列表理解的本地范围内,也不在全局范围内,但它在foo范围内。根据给定的Python范围规则,如果在本地范围内找不到变量,则将在封闭范围内搜索该变量,直到达到全局范围为止。在您的示例中,foo的作用域位于本地作用域和全局作用域之间,因此bar将在到达搜索结束之前找到。

然而,这仍然与exec示例不同,在exec示例中,您传入的本地范围并不包含列表推导的范围,而是与其完全分开的。

可以在这里找到范围界定规则的另一种很好的解释,包括插图:http
:
//sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/653367.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号