如何导入.pyc编译的python文件并使用它 [英] How can I import a .pyc compiled python file and use it

查看:171
本文介绍了如何导入.pyc编译的python文件并使用它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚如何在python脚本中包含 .pyc 文件.

Im trying to figure out how to include a .pyc file in a python script.

例如,我的脚本称为:

myscript.py

和我想包含的脚本称为:

and the script I would like to include is called:

included_script.pyc

所以,我只使用:

import included_script

这会自动执行 included_script.pyc 吗?还是我需要做进一步的事情来使我的 included_script.pyc myscript.py 内部运行?

And will that automatically execute the included_script.pyc ? Or is there something further I need to do, to get my included_script.pyc to run inside the myscript.py?

我还需要传递 included_script.pyc 中使用的变量吗?如果是这样,将如何实现?

Do I need to pass the variables used in included_script.pyc also? If so, how might this be achieved?

推荐答案

很遗憾,,这不能自动完成.当然,您可以用粗暴的丑陋方式手动进行.

Unfortunately, no, this cannot be done automatically. You can, of course, do it manually in a gritty ugly way.

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

For demonstration purposes, I'll first generate a .pyc file. In order to do that, we first need a .py file for it. Our sample test.py file will look like:

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

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

超级简单.生成 .pyc 文件可以使用 py_compile 模块.我们只需按照以下方式传入 .py 文件的名称和 .pyc 文件的名称:

Super simple. Generating the .pyc file can done with the py_compile module found in the standard library. We simply pass in the name of the .py file and the name for our .pyc file in the following way:

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

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

This will place mypyc.pyc in our current working directory.

现在, .pyc 文件包含按以下方式结构化的字节:

Now, .pyc files contain bytes that are structured in the following way:

  • 前4个字节表示魔数"
  • 接下来的4个字节保存着修改时间戳记
  • 其余内容均为编组 code 对象.

我们需要的是经过编组的 code 对象,因此我们需要

What we're after is that marshalled code object, so we need to import marshal to un-marshall it and execute it. Additionally, we really don't care/need the 8 first bytes, and un-marshalling the .pyc file with them is disallowed, so we'll ignore them (seek past them):

import marshal

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

因此,现在我们有了用于 test.py 的漂亮的 code 对象,该对象有效并且可以按我们希望的方式执行.我们在这里有两个选择:

So, now we have our fancy code object for test.py which is valid and ready to be executed as we wish. We have two options here:

  1. 在当前的 global 命名空间中执行它.这会将所有定义绑定到当前名称空间的 .pyc 文件中,并且将充当以下类型: from file import * 语句.

  1. Execute it in the current global namespace. This will bind all definitions inside our .pyc file in the current namespace and will act as a sort of: from file import * statement.

创建一个新的模块对象,并在模块内部执行代码.这将类似于 import file 语句.

Create a new module object and execute the code inside the module. This will be like the import file statement.


从文件导入中模拟 * ,例如:

执行此操作非常简单,只需执行以下操作即可:


Emulating from file import * like behaviour:

Performing this is pretty simple, just do:

exec(code_obj)

这将执行当前名称空间的 code_obj 中包含的代码,并将那里的所有内容绑定.通话后,我们可以像调用其他任何功能一样调用 foo :

This will execute the code contained inside code_obj in the current namespace and bind everything there. After the call we can call foo like any other funtion:

foo()
# prints: In foo!

注意: exec()是内置的.

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

This includes another requirement, the types module. This contains the type for ModuleType which we can use to create a new module object. It takes two arguments, the name for the module (mandatory) and the documentation for it (optional):

m = types.ModuleType("Fancy Name", "Fancy Documentation")

print(m)
<module 'Fancy Name' (built-in)>

现在我们有了模块对象,我们可以再次使用 exec 来执行模块命名空间内的 code_obj 中包含的代码(即 m .__ dict__):

Now that we have our module object, we can again use exec to execute the code contained in code_obj inside the module namespace (namely, m.__dict__):

exec(code_obj, m.__dict__)

现在,我们的模块 m 具有在 code_obj 中定义的所有内容,您可以通过运行以下命令进行验证:

Now, our module m has everything defined in code_obj, you can verify this by running:

m.foo() 
# prints: In foo


这些是您可以在模块中包含" .pyc 文件的方法.至少,我能想到的方式.我真的看不到这种做法的实用性,但是,嘿,我不是来这里评判的.


These are the ways you can 'include' a .pyc file in your module. At least, the ways I can think of. I don't really see the practicality in this but hey, I'm not here to judge.

这篇关于如何导入.pyc编译的python文件并使用它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆