[英]How can I import a .pyc compiled python file and use it
Im trying to figure out how to include a .pyc
file in a python script. 我试图弄清楚如何在python脚本中包含.pyc
文件。
For example my script is called: 例如,我的脚本被调用:
myscript.py
and the script I would like to include is called: 我想要包含的脚本称为:
included_script.pyc
So, do I just use: 那么,我只是使用:
import included_script
And will that automatically execute the included_script.pyc
? 那会自动执行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
在myscript.py
运行?
Do I need to pass the variables used in included_script.pyc
also? 我是否还需要传递included_script.pyc
使用的变量? 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. 当然,你可以用坚韧不拔的方式手动完成。
For demonstration purposes, I'll first generate a .pyc
file. 出于演示目的,我将首先生成.pyc
文件。 In order to do that, we first need a .py
file for it. 为此,我们首先需要一个.py
文件。 Our sample test.py
file will look like: 我们的示例test.py
文件如下所示:
def foo():
print("In foo")
if __name__ == "__main__":
print("Hello World")
Super simple. 超级简单。 Generating the .pyc
file can done with the py_compile
module found in the standard library. 生成.pyc
文件可以使用标准库中的py_compile
模块完成。 We simply pass in the name of the .py
file and the name for our .pyc
file in the following way: 我们只需通过以下方式传入.py
文件的名称和.pyc
文件的名称:
py_compile.compile('test.py', 'mypyc.pyc')
This will place mypyc.pyc
in our current working directory. 这会将mypyc.pyc
放在我们当前的工作目录中。
.pyc
files: 从.pyc
文件获取代码: Now, .pyc
files contain bytes that are structured in the following way: 现在, .pyc
文件包含以下列方式构造的字节:
code
object. 其余内容是编组的 code
对象。 What we're after is that marshalled code
object, so we need to import marshal
to un-marshall it and execute it. 我们所追求的是编组的code
对象,因此我们需要import marshal
来解组并执行它。 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): 另外,我们真的不关心/需要8个第一个字节,并且不允许用它们解组.pyc
文件,因此我们将忽略它们( seek
它们):
import marshal
s = open('mypyc.pyc', 'rb')
s.seek(8) # go past first eight bytes
code_obj = marshal.load(s)
So, now we have our fancy code
object for test.py
which is valid and ready to be executed as we wish. 所以,现在我们为test.py
提供了我们的花式code
对象,该对象是有效的并且可以随意执行。 We have two options here : 我们有两个选择 :
Execute it in the current global
namespace. 在当前global
命名空间中执行它。 This will bind all definitions inside our .pyc
file in the current namespace and will act as a sort of: from file import *
statement. 这将绑定当前命名空间中.pyc
文件中的所有定义,并将作为一种: from file import *
语句。
Create a new module object and execute the code inside the module. 创建一个新的模块对象并执行模块内的代码。 This will be like the import file
statement. 这将像import file
语句。
from file import *
like behaviour: from file import *
模拟行为: Performing this is pretty simple, just do: 执行此操作非常简单,只需:
exec(code_obj)
This will execute the code contained inside code_obj
in the current namespace and bind everything there. 这将执行当前命名空间中code_obj
中包含的代码并绑定其中的所有内容。 After the call we can call foo
like any other funtion: 通话结束后,我们可以像任何其他功能一样调用foo
:
foo()
# prints: In foo!
Note : exec()
is a built-in. 注意 : exec()
是内置的。
import file
like behaviour: 像行为一样模拟import file
: This includes another requirement, the types
module. 这包括另一个要求, types
模块。 This contains the type for ModuleType
which we can use to create a new module object. 它包含ModuleType
的类型,我们可以使用它来创建新的模块对象。 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)>
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__
):
exec(code_obj, m.__dict__)
Now, our module m
has everything defined in code_obj
, you can verify this by running: 现在,我们的模块m
具有code_obj
定义的code_obj
,您可以通过运行以下命令来验证:
m.foo()
# prints: In foo
These are the ways you can 'include' a .pyc
file in your module. 这些是您可以在模块中“包含” .pyc
文件的方法。 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. 我真的没有看到这方面的实用性,但是嘿,我不是来判断的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.