如何从.py文件手动生成.pyc文件


128

由于某种原因,我不能依靠Python的“ import”语句来自动生成.pyc文件

有没有一种方法可以实现以下功能?

def py_to_pyc(py_filepath, pyc_filepath):
    ...

Answers:


241

您可以compileall在终端中使用。以下命令将递归进入子目录,并为找到的所有python文件创建pyc文件。该compileall模块是Python标准库的一部分,所以你不需要安装任何额外的使用它。这对于python2和python3完全相同。

python -m compileall .

4
这应该是公认的答案-至少在我需要将所有* .py编译为* .pyc:递归:)
swdev 2014年

1
是否可以分发包含所有使用的库的PYC文件?因此,用户不必安装它们,只需运行PYC文件,我知道在Java中可以使用JAR来实现,是否有任何类似的Python方法?
D.Snap

我还听到了一些有关Python中的元文件的信息。这个compileall还建立一些缓存吗?如果没有,那么命令是什么?由于最终用户没有对lib目录的写许可权。我想加快这里的速度... PS。还可以查看-O标志,用于字节码(.pyo文件iso .pyc)编译。
危险89年

反编译呢?
Sajuuk

1
请谨慎使用此命令。我确实compileall在我的site-packages文件夹上做了一个意外操作,它弄乱了所有内容
Alex

58

您可以使用以下命令从命令行编译单个文件:

python -m compileall <file_1>.py <file_n>.py

55

自从我上一次使用Python已经有一段时间了,但是我相信您可以使用py_compile

import py_compile
py_compile.compile("file.py")

8
您可能想要包括第二个参数,该参数确定输出文件。否则,它默认为类似的值__pycache__/file.cpython-32.pyc,您将其作为返回值。
rvighne 2014年

46

我发现几种将python脚本编译成字节码的方法

  1. py_compile在终端中使用:

    python -m py_compile File1.py File2.py File3.py ...

    -m 指定要编译的模块名称。

    或者,用于文件的交互式编译

    python -m py_compile -
    File1.py
    File2.py
    File3.py
       .
       .
       .
  2. 使用py_compile.compile

    import py_compile
    py_compile.compile('YourFileName.py')
  3. 使用py_compile.main()

    它一次编译几个文件。

    import py_compile
    py_compile.main(['File1.py','File2.py','File3.py'])

    该列表可以根据需要增加。或者,您显然可以在命令行args中传递主要甚至文件名中的文件列表。

    或者,如果您传入['-']main,则它可以交互式地编译文件。

  4. 使用compileall.compile_dir()

    import compileall
    compileall.compile_dir(direname)

    它编译提供的目录中存在的每个Python文件。

  5. 使用compileall.compile_file()

    import compileall
    compileall.compile_file('YourFileName.py')

看一下下面的链接:

https://docs.python.org/3/library/py_compile.html

https://docs.python.org/3/library/compileall.html


一个小的修正是模块名称你是加载py_compilecompileall不是py_compile.pycompileall.py。换句话说,它应该是python3 -m py_compile PYTHON_FILENAMEpython3 -m compileall PYTHON_FILES_DIRECTORY
Devy

17

我会用compileall。从脚本和命令行都可以很好地工作。它比已经在内部使用的py_compile更高级别的模块/工具。


compileall不包含跳过相应.pyc文件已经为最新的文件的逻辑,对吗?
凯尔·斯特兰德

2
@KyleStrand compileall不跳过已经有一个了最新的文件.pyc(与Python测试2.7.11)
齐名

@Eponymous有趣。不知道为什么我不这样认为。感谢您的检查。
凯尔·斯特兰德

6

在Python2中,您可以使用:

python -m compileall <pythonic-project-name>

这样就可以全部编译.py.pyc包含子文件夹的项目中。


在Python3中,您可以使用:

python3 -m compileall <pythonic-project-name>

这样就可以全部编译.py__pycache__项目中包含子文件夹的文件夹中。

或从这篇文章中褐变:

您可以.pyc使用以下命令在文件夹中强制执行与Python2中相同的文件布局:

python3 -m compileall -b <pythonic-project-name>

该选项-b触发.pyc文件输出到其旧位置(即与Python2中相同)。


3

为了匹配原始问题要求(源路径和目标路径),代码应如下所示:

import py_compile
py_compile.compile(py_filepath, pyc_filepath)

如果输入代码有错误,则会引发py_compile.PyCompileError异常。


1

有两种方法可以做到这一点

  1. 命令行
  2. 使用python程序

如果使用命令行,则将python -m compileall <argument>python代码编译为python二进制代码。例如:python -m compileall -x ./*

或者, 您可以使用此代码将您的库编译为字节代码。

import compileall
import os

lib_path = "your_lib_path"
build_path = "your-dest_path"

compileall.compile_dir(lib_path, force=True, legacy=True)

def compile(cu_path):
    for file in os.listdir(cu_path):
        if os.path.isdir(os.path.join(cu_path, file)):
            compile(os.path.join(cu_path, file))
        elif file.endswith(".pyc"):
            dest = os.path.join(build_path, cu_path ,file)
            os.makedirs(os.path.dirname(dest), exist_ok=True)
            os.rename(os.path.join(cu_path, file), dest)

compile(lib_path)

看看☞docs.python.org详细资料

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.