如何将一串Python代码编译成一个可以调用其函数的模块?

时间:2013-11-08 01:44:50

标签: python

在Python中,我有一些包含以下函数的Python源代码:

mySrc = '''
def foo():
    print("foo")

def bar():
    print("bar")
'''

我想将这个字符串编译成某种类似模块的对象,这样我就可以调用代码中包含的函数了。

这是我想要做的伪代码:

myMod = myCompile(mySrc)
myMod.foo()

这在Python中可行吗?我试过这个,但它不起作用:

myMod = compile(mySrc, '', 'exec')
myMod.foo()

这会产生如下错误消息:

<code object <module> at 0x104154730, file "", line 1>Traceback (most recent call last):
  File "myfile.py", line XX, in run
    myMod.foo()
AttributeError: 'code' object has no attribute 'foo'

2 个答案:

答案 0 :(得分:18)

你必须编译并执行它:

myMod = compile(mySrc, '', 'exec')
exec(myMod)
foo()

您可以将词组传递给exec以阻止foo“泄露”。将它与使用types.ModuleType

创建的模块对象相结合
from types import ModuleType
…
compiled = compile(mySrc, '', 'exec')
module = ModuleType("testmodule")
exec(compiled, module.__dict__)

答案 1 :(得分:1)

在Python 2中,您需要神奇的compiler package

>>> import compiler
>>> mod = compiler.parseFile("doublelib.py")
>>> mod
Module('This is an example module.\n\nThis is the docstring.\n',
       Stmt([Function(None, 'double', ['x'], [], 0,
                      'Return twice the argument',
                      Stmt([Return(Mul((Name('x'), Const(2))))]))]))
>>> from compiler.ast import *
>>> Module('This is an example module.\n\nThis is the docstring.\n',
...    Stmt([Function(None, 'double', ['x'], [], 0,
...                   'Return twice the argument',
...                   Stmt([Return(Mul((Name('x'), Const(2))))]))]))
Module('This is an example module.\n\nThis is the docstring.\n',
       Stmt([Function(None, 'double', ['x'], [], 0,
                      'Return twice the argument',
                      Stmt([Return(Mul((Name('x'), Const(2))))]))]))
>>> mod.doc
'This is an example module.\n\nThis is the docstring.\n'
>>> for node in mod.node.nodes:
...     print node
...
Function(None, 'double', ['x'], [], 0, 'Return twice the argument',
         Stmt([Return(Mul((Name('x'), Const(2))))]))
>>> func = mod.node.nodes[0]
>>> func.code
Stmt([Return(Mul((Name('x'), Const(2))))])

在Python 3中,它是built right in