简体   繁体   English

如何在Python3中直接引用exec编译函数?

[英]How to directly refer to the exec compiled function in Python3?

I used to create a exec statement to generate a function to use in Python2. 我曾经创建一个exec语句来生成要在Python2中使用的函数。 However, when I move to Python3, the same approach stopped work ing. 但是,当我使用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
>>> 

In Python 3, the exec function is no longer able to modify the local scope directly. 在Python 3中, exec函数不再能够直接修改本地范围。

This is documented in exec() , see the note which says: 记录在exec() ,请参见注释:

Note: The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. 注意:默认本地语言的行为与下面对函数locals()描述相同:不应尝试对默认本地字典进行修改。 Pass an explicit locals dictionary if you need to see effects of the code on locals after function exec() returns. 如果需要在函数exec()返回后查看代码对本地语言的影响,请传递一个明确的本地语言字典。

Also note that the Python 2 code is using the exec statement , even though you wrote it to look like a function, it's a completely different form. 还要注意,Python 2代码正在使用exec语句 ,即使您将其编写为看起来像函数一样,它也是一种完全不同的形式。 See also this answer for a more in-depth discussion, or even this answer which covers this issue from a Python code disassembly point of view. 另见这个答案进行了较深入的讨论,甚至这个答案这从一个Python代码拆卸点涵盖了这个问题。

So, if you want to access the symbols defined in the scope of the exec() , you should pass it a dict (possibly empty, or pre-populated with any variable assignments or function definitions you want to use in your exec() block) and access it afterwards. 因此,如果要访问在exec()范围内定义的符号,则应向其传递一个dict(可能为空,或预先填充要在exec()块中使用的任何变量赋值或函数定义exec() ),然后再访问它。

This code works in Python 3: 此代码工作在Python 3:

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

Hopefully this should be good enough for your purposes. 希望这对于您的目的已经足够了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM