如何在运行时编译函数?
有没有在Python 3.x中使用标准库在运行时编译函数并通过函数对象使用它的方法?如何在运行时编译函数?
我试过如下:
class A:
def meth1(self, par1):
print("in A.meth1: par1 =", par1)
a = A()
s = '''def meth1(self, par1):
print("in recompiled A.meth1: par1 = ", par1)'''
a.meth1.__func__.__code__ = compile(s, __file__, "exec")
a.meth1("via meth1")
但是,这给出了一个错误:
TypeError:
<module>(
) takes 0 positional arguments but 2 were given
在为compile()
它writen与它编译的代码可以与eval()
或exec()
运行的文档。有没有办法编译一个函数,并通过没有eval()和exec()的函数对象来调用它?
你可能有过exec()
或eval()
运行它只是执行功能定义。您可以将它传递给一个单独的环境,您必须自己从中提取该函数(正如用户HelloWorld正确表示的那样,Python不能“猜测”您的意思)。
回到你的例子,在这里我首先创建一个空的环境environment
,然后将编译的代码和字典传递给exec
以评估定义。使用types库中的MethodType
类,必须将该函数转换为绑定方法,将该类或实例作为第二个参数提供。然后,您可以将绑定方法附加到原始实例。
import types
class A:
def meth1(self, par1):
print("in A.meth1: par1 =", par1)
a = A()
s = '''def meth1(self, par1):
print("in recompiled A.meth1: par1 = ", par1)'''
code = compile(s, __file__, "exec")
environment = {}
exec(code, environment)
a.meth1 = types.MethodType(environment["meth1"], A)
a.meth1("via meth1")
几乎是魔法。谢谢! –
jojonas给出了一个很好的答案,这个帖子是一个额外的评论比答案。
您不能简单地编译一个字符串并从类中替换代码对象。在您调用compile
后得到的是一个代码对象。例如。看看下面的代码。
obj = '''
def meth1(self, par1):
print("in recompiled A.meth1: par1 = ", par1)
def meth2(self, par1):
print("in recompiled A.meth2: par1 = ", par1)
'''
a.meth1.__func__.__code__ = compile(obj, __file__, "exec") # What should happen here?
正如你从这个例子中看到的,我们编译了一个不能简单地附加到类的整个范围。你需要做的是从代码对象中提取meth1
函数,然后使用它。
你应该看看下面有关代码对象的漂亮文章,它给你一些很好的见解。
http://late.am/post/2012/03/26/exploring-python-code-objects.html
感谢您的链接,我会检查它。 –
我想知道问题是什么,需要自修改代码作为解决方案? –
@Roland我试图使用一些仅在运行时才知道的信息(速度增强)。 –
也许你应该发表一个问题如何处理这个问题,但有更多的细节。可能有更好的方法。我假设你已经对代码进行了剖析,以显示程序大部分时间花在哪里? –