大家好,很高兴再次与大家见面,我是全栈君。
Python 文件常见的后缀名包括:
py、
pyc、
pyo、
pyi、
pyw、
pyd、
pyx等。本文将重点介绍其中较为常见的几种后缀名。至于一些较为冷门的文件格式,如
pyz、
pywz、
rpy、
pyde、
pyp、
pyt等,由于资料稀少,网上相关文章大多来源相同且内容简略,因此本文不作深入探讨。
py是最常见的 Python 源代码文件。
实际上,如果使用
python + 文件的方式运行代码,只要文件内容相同,后缀名并不重要。以下运行结果是等价的:
python test.pypython test.txtpython test
pyc是常见的 Python 字节码缓存文件。
立即学习“Python免费学习笔记(深入)”;
pyc文件和
py文件一样可以直接执行,以下运行结果是等价的:
python test.pypython test.pyc
pyc文件有两个主要作用:
作用一:提升加载性能。当 Python 代码执行时,首先由 Python 解析器翻译成 PyCodeObject 对象(字节码),然后由 Python 解释器执行。每次运行程序时,翻译后的字节码保存在内存中,程序结束后即消失。为了提高加载效率,Python 会在程序结束后将每个文件的字节码写入硬盘,保存为
xxx.pyc文件。这样,下次执行该程序时,如果目录中有对应的
xxx.pyc文件且修改时间与
xxx.py文件一致,就可以直接读取
xxx.pyc文件执行,而无需再次翻译成字节码。尽管这种缓存方式对性能提升的效果有限,但在大型项目中效果显著。
默认情况下,并不是所有的
py文件都会自动生成
pyc文件,只有被其他文件 import 的文件才会生成对应的
pyc文件。可以通过一个简单的实验来验证:新建两个 Python 文件
hello.py和
import.py,内容如下:
# hello.pyprint("hello")# import.pyimport hello
直接运行
python hello.py不会生成
pyc文件,而运行
python import.py会在当前目录下生成
hello.py对应的
pyc文件。
Python2 和 Python3 在生成
pyc文件时有所不同:Python2 会在当前目录下生成同名的
pyc文件,而 Python3 会在当前目录下创建
__pycache__文件夹,并在其中生成包含 Python 版本信息的
xxx.cpython-37.pyc文件。
Python2
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695277971.jpg)
Python3
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695330351.jpg)
作用二:隐藏源代码。
pyc格式是为解释器设计的二进制文件,直接用编辑器打开会显示乱码。将 Python 代码编译成
pyc文件后再交付使用,可以在一定程度上隐藏源代码。
默认情况下,主文件不会生成
pyc文件,但可以通过 Python 自带的
py_compile或
compileall库,手动将所有
py文件编译成
pyc文件。
python -m py_compile *.pypython -m compileall *.py
Python2
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695310984.jpg)
Python3
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695399474.jpg)
反编译
pyc文件。虽然
pyc文件可以一定程度上隐藏源代码,但可以通过反编译工具恢复源码。
uncompyle6是一个专门用于将
pyc文件反编译为
py源码的第三方库,安装方式如下:
pip install uncompyle6
执行以下命令可以将生成的
pyc文件反编译为
py文件:
uncompyle6 -o . *.pyc
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695384239.jpg)
打开生成的文件
hello.cpython-37.py和
import.cpython-37.py,可以看到与之前的
py代码内容完全相同,只是多了一些 Python 版本信息。
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695312664.jpg)
要了解更多关于防止反编译的技术,请参考文章:通过字节码混淆来保护Python代码。
pyo是优化后的 Python 字节码缓存文件。
pyo文件的作用与
pyc文件相似,唯一的区别是
pyo文件去除了断言语句(
assert语句)。可以使用
py_compile或
compileall库将示例文件编译成
pyo文件,只需添加
-O参数,运行结果没有任何变化:
python -O -m py_compile *.pypython -O -m compileall *.py
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695383113.jpg)
从 Python3.5 开始,Python 只使用
pyc文件,不再使用
pyo文件。因此,以下命令无法生成
pyo文件,生成的依然是
pyc文件:
python3 -O -m py_compile *.pypython3 -O -m compileall *.py
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695338035.jpg)
pyi是 Python 的存根文件,用于代码检查时的类型提示。
pyi文件是
PEP484提案规定的用于 Python 代码类型提示(Type Hints)的文件。
PEP(Python Enhancement Proposals)是经过 Python 社区核心开发者讨论并一致同意后发布的正式规范文档,如 Python 之禅(
PEP20)、代码风格
PEP8格式化(
PEP8)、将
PEP3105)等。要了解更多关于
PEP的信息,请参考文章:学习Python,怎能不懂点PEP呢?。
常用的 IDE 都有类型检查提示功能,例如在 PyCharm 中,当给一个函数传入错误类型时会给出提示。这不是 IDE 的特殊开发功能,而是集成了
PEP484的规定,利用了预先生成的
pyi文件。
例如,
os.makedirs是标准库中用于创建文件夹路径的函数,其入参应为字符串类型。如果传入一个
int类型,IDE 会立刻给出提示。
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695337531.jpg)
按住
ctrl键点进去,会进入到
os模块定义
os.makedirs的地方,发现前面有一个
*号,鼠标放上去会提示
Has stub item in __init__.pyi。
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695468001.jpg)
点击
*号会跳转到对应的
__init__.pyi文件,该文件按照
PEP484规定,为
os模块的每个函数定义了对应的类型检查规则。
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695450971.jpg)
关于
pyi文件的定义规则及如何生成,请参考官方文档:PEP 484 – Type Hints。
pyw是一种 Python 源代码文件,通常只存在于 Windows 系统。
pyw文件和
py文件除了后缀名不同外没有任何区别,两者都是 Python 源码文件。如前所述,“如果使用
python + 文件的方式运行代码,只要文件内容相同,后缀名并不重要”,这一点在 Windows 和 Linux 系统上都是一致的。
在 Windows 系统上,新建两个内容相同的 Python 文件
hello.py和
hello.pyw,使用
python + 文件的方式运行,结果相同:
# hello.pyprint("hello")# hello.pywprint("hello")![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695457980.jpg)
那么,为什么还需要
pyw文件呢?
在 Windows 系统上,双击文件时,系统会根据文件扩展名调用关联的
exe程序来运行该文件。打开 Python 安装目录,可以看到有
python.exe和
pythonw.exe两个
exe文件,其中
python.exe关联了
py文件,
pythonw.exe关联了
pyw文件。与
python.exe相比,
pythonw.exe运行时不会弹出控制台窗口,
stdout、
stderr和
stdin都无效,因此像
stdout的操作不会有打印结果(因为没有 cmd 窗口显示)。
![Python 相关文件常见的后缀名详解[通俗易懂]](https://img.php.cn/upload/article/001/503/042/175642695438244.jpg)
因此,在开发 Python GUI 程序时,如果不想让程序运行时弹出黑色的 cmd 窗口,可以将源码文件的后缀名改为
pyw格式。不过,我个人认为
pyw格式的实际用处不大,因为很少有人通过双击
py或
pyw文件来运行 Python 代码。我之前使用
tkinter开发带 Windows 界面的 Python 程序时,是通过双击
bat脚本启动 Python 脚本来避免弹出黑框框的。
pyd是 Python 可直接调用的 C 语言动态链接库文件,通常只存在于 Windows 系统。
Python 是一种胶水语言,可以将对速度要求较高的代码使用 C 语言编写,编译成动态链接库文件,再通过 Python 调用。一般来说,在 Linux 上是
so文件,在 Windows 系统上是
DLL文件。
例如,有一个 C 语言编写的 Windows 动态链接库
test_lib.dll,编译前的代码如下:
int sum(int x, int y){ return x + y;}可以在 Python 代码中通过以下方式调用:
# test_lib.dll 放在当前目录下import ctypesfrom ctypes import *test_lib = ctypes.windll.LoadLibrary("test_lib.dll")a = ctypes.c_int(1)b = ctypes.c_int(2)out = test_lib.sum(a, b)print(out) # 3在 Windows 系统上,Python 还有一种
pyd格式的动态链接库。上述调用方式是先通过
ctypes.windll.LoadLibrary方法将动态链接库加载进来,而
pyd格式可以在 Python 代码中直接
import进来,类似如下:
# test_lib.pyd 放在当前目录下import test_libout = test_lib.sum(1, 2)print(out) # 3
关于
pyd文件和
DLL文件的区别,请参考官方文档的说明。
C 语言代码和 Python 代码都可以通过一定的方法编译成
pyd格式的文件,我个人没有实际使用过
pyd文件,详细方法可参考以下文章:
使用C++创建Pyd文件扩展Python模块
Python源代码保护(Python文件编译生成pyd/so库文件)
pyx是 Cython 源代码文件。
注意是 Cython 而不是 CPython。Cython 是一种结合了 Python 语法和 C/C++ 效率的编程语言。用 Cython 编写的代码可以很容易转成 C 语言代码,然后编译成动态链接库(
pyd或
DLL)供 Python 调用。因此,Cython 通常用于编写 Python 的 C 扩展。Cython 的源代码文件通常使用
pyx后缀。
总结
| 后缀名 | 作用 |
|---|---|
| py | 最常见的 Python 源代码文件。 |
| pyc | 常见的 Python 字节码缓存文件,可以反编译成 py 文件。 |
| pyo | 另一种 Python 字节码缓存文件,只存在于 Python2 及 Python3.5 之前的版本。 |
| pyi | Python 的存根文件,常用于 IDE 代码格式检查时的类型提示。 |
| pyw | 另一种 Python 源代码文件,一般只存在于 Windows 系统。 |
| pyd | 一种 Python 可直接调用的 C 语言动态链接库文件,一般只存在于 Windows 系统。 |
| pyx | Cython 源代码文件,一般用来编写 Python 的 C 扩展。 |
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://www.php.cn/link/81dd4df7529a4765132f4425191d1715
原文链接:https://www.php.cn/link/c8377ad2a50fb65de28b11cfc628d75c










