使用字节码导入 python 模块而不使用源代码

Pra*_*vol 5 python python-import python-3.x

来自Python书籍:

学习Python。第五版,第 #727 页

我读了以下内容:

如果Python在搜索路径上只找到一个字节码文件并且没有找到源代码,那么它只是直接加载字节码;这意味着您可以将程序仅作为字节代码文件发送,并避免发送源代码

但是当在 Python 3.5 上尝试相同的操作时,它不起作用:

~/Python/Module_Test$ cat a.py
a = "abc"
l = [1,2,3]
Run Code Online (Sandbox Code Playgroud)

导入模块'a'创建的字节码文件如下:

~/Python/Module_Test/__pycache__$ ls
a.cpython-35.pyc
Run Code Online (Sandbox Code Playgroud)

现在我删除了该'a.py'文件并从字节码目录中导入了该模块'a'

~/Python/Module_Test/__pycache__$ python
Python 3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul  2 2016, 17:53:06) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'a'
Run Code Online (Sandbox Code Playgroud)

我什至尝试将字节码目录添加到搜索路径,但仍然无法加载模块:

>>> import sys
>>> sys.path.append('/home/pradeep/Python/Module_Test/__pycache__')
>>> import a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'a'
Run Code Online (Sandbox Code Playgroud)

我做错了什么?我们可以在没有源代码的情况下从字节代码导入模块吗?难道我对书上的说法的理解有误?

Jim*_*ard 1

你的理解没有错;你可以,但是,这样做并不是最好的主意。据我所知,该import语句的默认行为本身不会执行此操作,您需要使用 中已弃用的函数imp、编写自己的函数或自定义导入过程来执行此操作。

对于imp,您可以load_compiled这样使用:

from imp import load_compiled

mod = load_compiled('a', '__pycache__/a.cpython-35.pyc')
Run Code Online (Sandbox Code Playgroud)

导入您的模块。a.py我知道 Python 所做的值得注意的事情是,如果对应的模块*.pyc存在并且仍然有效,它不会重新编译该模块。