python - 如何直接引用Python3中的exec编译函数?

标签 python python-3.x exec

我曾经创建一个 exec 语句来生成一个在 Python2 中使用的函数。然而,当我转向 Python3 时,同样的方法就不再起作用了。

Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def a():
...   exec(compile("def printt(): print(2)","printt","exec"))
...   printt()
... 
>>> a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in a
NameError: name 'printt' is not defined
>>>
<小时/>
Python 2.7.15+ (default, Nov 27 2018, 23:36:35) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def a():
...   exec(compile("def printt(): print(2)","printt","exec"))
...   printt()
... 
>>> a()
2
>>> 

最佳答案

在 Python 3 中,exec 函数不再能够直接修改本地作用域。

这记录在exec()中,请参阅注释:

Note: The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. Pass an explicit locals dictionary if you need to see effects of the code on locals after function exec() returns.

另请注意,Python 2 代码使用 exec statement ,尽管你把它写得看起来像一个函数,但它是一种完全不同的形式。另请参阅this answer进行更深入的讨论,甚至this answer它从Python代码反汇编的角度涵盖了这个问题。

因此,如果您想访问在 exec() 范围内定义的符号,您应该向其传递一个字典(可能是空的,或者预先填充了任何变量赋值或函数定义)您想在 exec() block 中使用)并随后访问它。

此代码works在 Python 3 中:

def a():
   namespace = {}
   exec(compile("def printt(): print(2)","printt","exec"),
        globals(), namespace)
   printt = namespace['printt']
   printt()

希望这足以满足您的目的。

关于python - 如何直接引用Python3中的exec编译函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57142799/

相关文章:

python - Python 2 和 Python 3 中 exec 函数的行为

python - 如何将集合中的元素与多个字典条目关联

Python - 请求拉取 HTML 而不是 JSON

python - 如何通过保护只有经过身份验证的用户才能看到的 url 来使文件私有(private)

python - 使用 beautifulsoup 从维基百科表中获取列

python - x += y 和 x = x + y 之间的区别

vb.net - 如何启动带参数的exe

linux - 过滤 Bash session 中的所有输出

python - 从元素不立即加载的表中抓取数据

python - 如何构建依赖大型系统库的Python包