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

180

出于某些原因,我无法依靠Python的"import"语句自动生成.pyc文件

是否有一种实现以下函数的方法?

def py_to_pyc(py_filepath, pyc_filepath):
    ...
9个回答

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

6
这应该是被接受的答案,至少在我需要递归地将所有*.py编译成*.pyc的情况下是这样的。 - swdev
2
有没有可能分发一个包含所有库的PYC文件?这样用户就不必安装它们,只需运行PYC文件。我知道在Java中使用JAR是可能的,那么Python有类似的方法吗? - D.Snap
3
请注意这个命令。我不小心在我的site-packages文件夹上执行了compileall命令,这导致了一切都出现了问题。请小心操作。 - Alex
我正在使用Anaconda Python发行版。它位于ProgramData子文件夹中,我不想在那里存储我的.py文件。如何使用此命令编译特定文件夹? - ColinMac
递归地查找/py_files_folders目录下所有的后缀为“.py”的文件,并执行“python -m compileall {} ;”命令。 - FabricioFCarv
显示剩余5条评论

75

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

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

66

我已经有一段时间没有用Python了,但我相信你可以使用py_compile

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

13
你可能需要包含第二个参数,它确定输出文件。否则,默认情况下会生成类似于“pycache/file.cpython-32.pyc”的文件,并将其作为返回值。 - rvighne

61

我找到了几种将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

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

    它可以同时编译多个文件。

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

    列表可以随意增长。或者,您也可以在main函数中传递文件列表,甚至是命令行参数中的文件名。

    或者,如果您在主函数中传递['-'],则它可以交互地编译文件。

  6. 使用compileall.compile_dir()

  7. import compileall
    compileall.compile_dir(direname)
    

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

  8. 使用compileall.compile_file()

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

请查看下面的链接:

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

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


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

19

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


compileall 是否包含跳过已经是最新的 .pyc 文件的逻辑呢? - Kyle Strand
4
compileall 命令会跳过已经存在最新的 .pyc 文件的文件(在 Python 2.7.11 中测试过)。 - Eponymous
@Eponymous 很有趣。不确定为什么我会有其他想法。感谢您的检查。 - Kyle Strand

18

通常以下命令编译Python项目:

python -m compileall <project-name>

在Python2中,对于包含模块和包的项目,它会将所有的.py文件编译成.pyc文件。

而在Python3中,对于包含模块和包的项目,它会将所有的.py文件编译到__pycache__文件夹中。

根据这篇文章的提示:

你可以使用以下命令强制让.pyc文件与Python2中相同的布局方式生成:

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

选项-b会触发输出.pyc文件到它们遗留的位置(就像在Python2中一样)。


4
为了满足原始问题要求(源路径和目标路径),代码应该像这样:
import py_compile
py_compile.compile(py_filepath, pyc_filepath)

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

1
  1. 在该文件所在的目录中创建一个新的Python文件。
  2. 键入import(文件名不带扩展名)
  3. 运行该文件
  4. 打开目录,然后找到pycache文件夹
  5. 里面应该是你的.pyc文件

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 moveToNewLocation(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)

moveToNewLocation(lib_path)

查看详细文档,请访问☞ docs.python.org


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接