Ke.*_*Ke. 2 python import file include
我试图弄清楚如何.pyc
在 python 脚本中包含一个文件。
例如我的脚本被称为:
myscript.py
Run Code Online (Sandbox Code Playgroud)
我想包含的脚本被称为:
included_script.pyc
Run Code Online (Sandbox Code Playgroud)
那么,我是否只使用:
import included_script
Run Code Online (Sandbox Code Playgroud)
那会自动执行included_script.pyc
吗?或者我还需要做些什么才能让我included_script.pyc
在myscript.py
.
我还需要传递使用的变量included_script.pyc
吗?如果是这样,如何实现?
不幸的是,不,这不能自动完成。当然,您可以以非常丑陋的方式手动完成。
出于演示目的,我将首先生成一个.pyc
文件。为了做到这一点,我们首先需要一个.py
文件。我们的示例test.py
文件将如下所示:
def foo():
print("In foo")
if __name__ == "__main__":
print("Hello World")
Run Code Online (Sandbox Code Playgroud)
超级简单。.pyc
可以使用py_compile
标准库中的模块生成文件。我们只需通过以下方式传入.py
文件名和文件名.pyc
:
py_compile.compile('test.py', 'mypyc.pyc')
Run Code Online (Sandbox Code Playgroud)
这将放置mypyc.pyc
在我们当前的工作目录中。
.pyc
文件中获取代码:现在,.pyc
文件包含按以下方式构造的字节:
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)
Run Code Online (Sandbox Code Playgroud)
所以,现在我们有我们的幻想code
对象,test.py
它是有效的,可以按照我们的意愿执行。我们在这里有两个选择:
在当前global
命名空间中执行它。这将绑定.pyc
当前命名空间中我们文件中的所有定义,并将作为一种:from file import *
语句。
创建一个新的模块对象并执行模块内的代码。这将类似于import file
声明。
from file import *
类似的行为:执行此操作非常简单,只需执行以下操作:
exec(code_obj)
Run Code Online (Sandbox Code Playgroud)
这将执行code_obj
当前命名空间中包含的代码并将所有内容绑定到那里。在调用之后,我们可以foo
像任何其他函数一样调用:
foo()
# prints: In foo!
Run Code Online (Sandbox Code Playgroud)
注意:exec()
是内置的。
import file
类似的行为:这包括另一个要求,即types
模块。这包含ModuleType
我们可以用来创建新模块对象的类型。它需要两个参数,模块的名称(必需)和它的文档(可选):
m = types.ModuleType("Fancy Name", "Fancy Documentation")
print(m)
<module 'Fancy Name' (built-in)>
Run Code Online (Sandbox Code Playgroud)
现在我们有了我们的模块对象,我们可以再次使用exec
来执行包含在code_obj
模块命名空间(即m.__dict__
)中的代码:
exec(code_obj, m.__dict__)
Run Code Online (Sandbox Code Playgroud)
现在,我们的模块m
在 中定义了所有内容code_obj
,您可以通过运行来验证这一点:
m.foo()
# prints: In foo
Run Code Online (Sandbox Code Playgroud)
这些是您可以.pyc
在模块中“包含”文件的方法。至少,我能想到的方法。我并没有真正看到它的实用性,但是嘿,我不是来判断的。