我试图在不保留.py个源文件的情况下运行Python应用程序,并且只依赖.pyc个编译文件.但是,当我删除.py个源文件时,会出现导入错误.这个功能在Python2.7中可以使用,但在3.4中不能使用(使用新的__pycache__ struct ).

下面是一个示例目录 struct :

package/
  __init__.py
  module.py

Python 2.7

首先,让我们看看当我使用Python 2.7时会发生什么(这是所需的行为)

$ python2 -c "from package import module"
$ find package -name "*.py" -delete
$ python2 -c "from package import module"

一切都很好,没有错误.执行此操作后的目录 struct 如下所示,.pyc个文件与原始的.py个文件并列:

package/
  __init__.pyc
  module.pyc

Python 3.4

现在,让我们对Python3.4做同样的事情,再次从原始目录 struct 开始

$ python3 -c "from package import module"
$ find package -name "*.py" -delete
$ python3 -c "from package import module"
 Traceback (most recent call last):
   File "<string>", line 1, in <module>
 ImportError: cannot import name 'module'

哦,它不能导入模块.有趣的是,我现在仍然可以安全地运行python3 -c "import package",但它无法从那里获取任何模块.此时,目录 struct 看起来与2.7中的略有不同,具体如下:

package/
  __pycache__/
      __init__.cpython-34.pyc
      module.cpython-34.pyc

所以问题是:为什么Python3.4在只有.pyc个文件的情况下不能正确导入/执行?这是一种期望的行为吗?也就是说,在所有情况下都必须保留来源?还是我错过了什么蠢事?

推荐答案

根据the PEP:

有可能是foo.py文件不知何故被删除,而缓存的pyc文件仍保留在文件系统中.如果__pycache__/foo.<magic>.pyc文件存在,但是foo.用于创建它的py文件没有,当被要求导入foo时,Python将引发ImportError.换句话说,Python不会从缓存目录导入pyc文件,除非源文件存在.

但是:

不过,为了继续支持源代码较少的发行版,如果源文件丢失,Python将导入一个单独的pyc文件(如果它位于源文件所在的位置).

因此,似乎__pycache__和无源发行版是相互排斥的.如果要删除源,则需要移动源.将pyc文件导出到源文件所在的目录中.

Python-3.x相关问答推荐

使用pythonnet和nicegui时无法pickle December对象

如何从枚举中获取某个值?

Django 模型类方法使用错误的 `self`

为什么空列表也能起作用?

从列表的元素和python中的多个多索引数据帧执行方程

提高时间复杂度的一些建议

如何向 scikit-learn 函数添加类型提示?

BeautifulSoup 和 pd.read_html - 如何将链接保存到最终数据框中的单独列中?

为什么Pandas会在 NaN 上合并?

Tkinter AttributeError:对象没有属性'tk'

Python 解包运算符 (*)

使用逗号时,除了处理程序中的语法无效

我们如何获得 __repr__() 的默认行为?

如何调试垂死的 Jupyter Python3 内核?

如何在不使用 @hydra.main() 的情况下获取 Hydra 配置

如何在继承的数据类中创建可选字段?

TypeError:多个基地有实例布局冲突

Python 3 中的连接列表

TypeError: write() 参数必须是 str,而不是字节(Python 3 vs Python 2)

Python,Docker - ascii编解码器无法编码字符