- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
考虑以下片段:
def bar():
return 1
print([bar() for _ in range(5)])
它给出了预期的输出 [1, 1, 1, 1, 1]
。
但是,如果我尝试在空环境中exec
相同的片段(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]
就像在我的第一个 exec 中一样,我们在本地列表理解中没有障碍。但是,如果我们尝试调用它,它就会起作用!
最佳答案
您的问题的解决方案就在这里:
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 是在 locals
范围内定义的,并且仅在 locals
中定义。因此,这个 exec()
语句有效:
exec("""
def bar():
return 1
print(bar())
""", {}, {})
然而,列表理解创建了一个新的本地范围,其中 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 示例不同,在 exec 示例中,您传入的 locals 范围并未包含列表推导的范围,而是与其完全分开。
可以在此处找到包括插图在内的范围规则的另一个很好的解释:http://sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html
关于python - 在 exec 中用空局部变量列表理解 : NameError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45132645/
我正在尝试设置 rbenv: https://github.com/sstephenson/rbenv#section_2 我有一个问题:我必须在一切之前使用 rbenv exec 所以现在我要做 b
我已经使用我们的应用程序创建了图像,运行该图像后,我可以看到还创建了 docker 容器,当我尝试进入 docker 容器时,出现以下错误,请您在这里帮助我。 """"OCI runtime exec
这post on javapapers.com显示如何运行 JMH通过键入 mvn exec:exec 在 Maven 中进行基准测试。在 Maven 中运行 JMH 非常方便,因为您可以轻松地从 E
因为我是 shell 脚本的新手,exec命令总是让我感到困惑,同时用 while 探索这个话题循环触发了以下 4 个问题: 下面的语法 1 和 2 有什么区别 语法 1: while read LI
湖一看这两条线 案例 1 set cvsUpdStr [exec cvs -qn upd] 案例 2 set cvsUpdStr [exec cvs -qn upd >&@stdout] 对于第一种情
我有一个配置为使用 Maven 构建和运行的项目。该项目取决于平台特定的 native 库,我正在使用发现的策略 here管理这些依赖项。 本质上,特定平台的 .dll 或 .so 文件被打包到 ja
我发现 tcl exec 命令首先从标准输出返回字符串,然后是标准错误。例如,我下面的“测试脚本”按以下顺序生成消息: puts "test started" puts stderr "some no
我有 rpc error: code = 13 desc = invalid header field value "oci runtime error: exec failed: cannot ex
过去 2 天我遇到了一个问题。 我正在运行一个 tcl 脚本(用于 eggdrop),该脚本在被触发时执行本地 shell 命令(子进程),如果命令成功,它会输出结果。但是,如果命令不成功,我会收到错
假设我有一个像这样的 TCL 脚本: exec ls -l 现在这将打印出当前目录的内容。我需要将该输出作为字符串并解析它。我怎么能做到这一点? 最佳答案 exec返回输出,因此只需为其设置一个变量:
我正在尝试在 PHP 中使用 GNUPLOT 绘制正弦图,但是当我使用 exec 绘制该图时出现此错误: Warning: exec() [function.exec]: Cannot execute
我正在尝试 mvn exec:exec (或 mvn exec:java )使用类路径中的本地 jar 运行我的程序。但是 jar 无法加载: Exception in thread "main" j
我在最新的 Docker CLI 文档中注意到 Docker CLI 命令列表已经扩展。 如果我使用 码头执行 早些时候在容器内启动可执行文件现在我也可以使用 docker 容器执行 命令。 dock
这个问题在这里已经有了答案: Call to a member function exec() on a non-object error in PHP [duplicate] (1 个回答) 关闭
手册页说“exec() 系列函数用新的过程镜像替换当前的过程镜像。”但我不太明白“用新过程图像替换当前过程图像”的含义。比如exec成功,perror就达不到 execl("/bin/ls", /*
手册页说“exec() 系列函数用新的过程镜像替换当前的过程镜像。”但我不太明白“用新过程图像替换当前过程图像”的含义。比如exec成功,perror就达不到 execl("/bin/ls", /*
我正在 UrbanCode Deploy Shell 步骤中执行以下命令。我想要的是针对找到的所有文件运行 Util.sh。 find . -type f -exec ls -al {} \; fin
仅当将“-p”添加到 org.codehaus.mojo:exec-maven-plugin:1.6.0:exec 插件时,以下 pom.xml 执行才会失败,删除此参数后它运行正常,但我需要争论,有
我正在尝试进入 Maven 并开始编写一个小型库。作为库代码的一部分,我想要一个小型演示 Java 应用程序,可以用来查看库在做什么以及如何使用它。现在真正让我烦恼的一件事是,为了执行该演示,我必须执
我是 maven 的新手,在通过 maven 运行类文件时遇到问题 它运行良好 mvn exec:java -Dexec.mainClass="com.test.Test" 但不是 mvn exec:
我是一名优秀的程序员,十分优秀!