如何导入.pyc编译的python文件并使用它

时间:2016-01-10 18:45:54

标签: python file import include

我试图找出如何在python脚本中包含.pyc文件。

例如我的脚本被调用:

myscript.py

我想要包含的脚本叫做:

included_script.pyc

那么,我只是使用:

import included_script

这会自动执行included_script.pyc吗?或者我还需要做些什么,让included_script.pycmyscript.py内运行?

我还需要传递included_script.pyc中使用的变量吗?如果是这样,怎么可能实现呢?

1 个答案:

答案 0 :(得分:3)

不幸的是,没有,这不能自动完成。 当然,你可以用坚韧不拔的方式手动

设置:

出于演示目的,我将首先生成.pyc文件。为此,我们首先需要一个.py文件。我们的示例test.py文件如下所示:

def foo():
    print("In foo")

if __name__ == "__main__":
    print("Hello World")

超级简单。生成.pyc文件可以使用标准库中的 py_compile 模块完成。我们只是按以下方式传递.py文件的名称和.pyc文件的名称:

 py_compile.compile('test.py', 'mypyc.pyc')

这会将mypyc.pyc放在我们当前的工作目录中。

.pyc文件中获取代码:

现在,.pyc个文件包含以下列方式构造的字节:

  • 前4个字节表示一个幻数'
  • 包含修改时间戳的下一个4个字节
  • 其余内容是 marshalled code对象。

我们之后的目标是编组code对象,因此我们需要 import marshal 取消编组并执行它。此外,我们实际上并不关心/需要8个第一个字节,并且不允许使用它们对.pyc文件进行解组,因此我们会忽略它们(seek过去它们) :

import marshal

s = open('mypyc.pyc', 'rb')
s.seek(8)  # go past first eight bytes
code_obj = marshal.load(s)

所以,现在我们有code的{​​{1}}对象是有效的,可以按照我们的意愿执行。 我们在这里有两个选项

  1. 在当前test.py命名空间中执行它。这将绑定当前命名空间中global文件中的所有定义,并将作为一种:.pyc语句。

  2. 创建一个新的模块对象并执行模块内的代码。这与from file import *语句类似。

  3. 模仿import file之类的行为:

    执行此操作非常简单,只需:

    from file import *

    这将执行当前命名空间中exec(code_obj) 内包含的代码并绑定其中的所有内容。通话结束后,我们可以像其他任何功能一样致电code_obj

    foo

    注意foo() # prints: In foo! 是内置的。

    模仿exec()之类的行为:

    这包括另一项要求, types 模块。这包含 ModuleType 的类型,我们可以使用它来创建新的模块对象。它需要两个参数,模块的名称(必填)和它的文档(可选):

    import file

    现在我们有了模块对象,我们可以再次使用m = types.ModuleType("Fancy Name", "Fancy Documentation") print(m) <module 'Fancy Name' (built-in)> 来执行模块命名空间内exec中包含的代码(即code_obj):

    m.__dict__

    现在,我们的模块exec(code_obj, m.__dict__) 包含了m中定义的所有内容,您可以通过运行来验证这一点:

    code_obj

    这些是您可以包含&#39;的方法。模块中的m.foo() # prints: In foo 文件。至少,我能想到的方式。我真的没有看到这方面的实用性,但嘿,我不能在这里判断。