这样的流行程度也会暴露 Python 的缺点,最显著且众所周知的缺点是这三个:运算性能、打包及可执行程序的生成、项目管理
下面给大家讲讲 Python 程序员面临的这三个缺点,以及 Python 与其第三方工具开发人员提出的解决这些缺点的方法。
缺点一:Python 多线程和速度
Python 整体性能缓慢,有限的线程和多处理能力是其未来发展的主要障碍。
Python 长期以来一直重视编程的易用性而不是运行时的速度。当通过使用 C 或 C++ 编写的高速外部库(如 Numpy 和 Numba)在 Python 中完成如此多的性能密集型任务时,你会发现 Python 重视编程的易用性也是一种不错的选择。但是尽管如此,Python 的开箱即用的性能速度依然落后于其他语言,比如说具有同样简单语法的 Nim 和 Julia,却可以被编译为机器代码,具有更高的性能优势。
Python 无法全面利用多核处理器是其长久以来的问题,它确实具有线程功能,但它的线程功能是局限于单个核心的。虽然 Python 可以使用多进程,但是调度和同步这些子进程的结果并不总是有效的
解决方案
目前没有单一,自上而下的整体解决方案来解决 Python 的性能问题,不过我们有一系列加速 Python 的举措。比如说:
- 使用 PyPy 解释器替代官方解释器,PyPy 能够将 Python 代码编译成机器代码,它在仅仅使用 Python 自带的模块的代码中效果最好,不过现在也可以适用于如 numpy 这样的流行的库,但是其始终只适合于长期运行的服务,而不是能打包带走的应用程序。
- Cython,Cython 能将 Python+C 混合编码的.pyx 脚本转化为 C 代码。该项目最初是为科学和数值计算而设计的,但它可以在大多数情况下使用。
- Numba,Numba 和 Cython 类似,主要用于科学计算。
- Mypyc,是现在仍在开发的项目,它会将用 mypyc 类型装饰器装饰的代码转化为 C.
- 优化的 Python 发行版,比如英特尔针对特殊的处理器和其特殊的数学运算所开发的专门编译版本。不过尽管它能够显著加快部分运算速度,但不能加快整体的运算速度。
如果你是高手,你还能尝试摆脱一下 GIL(全局解释器锁),之所以 Python 的多线程是假的,就是因为 GIL 的存在:它用来保证 Python 同时只能有一个线程运行。因此从理论上来讲,如果你摆脱了 GIL,就能进行多线程运算,可以提高性能。
还有一个正在进行的项目能够解决许多速度提升的问题,即重构 Python 内部 C 接口的实现,一个不混乱的接口可以使得许多性能的改进成为可能。
缺点二:Python 打包和可执行文件
即使在 Python 诞生 30 年后,Python 依然没有很好的方法来生成可执行文件(exe 程序等)
解决方案
- pyinstaller 可以打包使用许多如 numpy 这样的库,但是它必须和这些库保持版本一致,这可太难受了。而且它生成的程序比较大,因为把 import 语句里所有的内容都封装在一起了。
- 还有种方法也是正在研究中,那就是 PyOxidizer 项目使用 Rust 语言生成嵌入 Python 的二进制文件,不过距离成为真正的解决方案还有一段发展路程要走。
缺点三:Python 包管理、项目管理
当你想将一个本地比较复杂的 Python 工程移植到服务器上的时候,你就知道 Python 项目管理是有多蛋疼了
解决方案
- 这种问题,当然需要 Python 的开发团队出手了,需要他们提供一套优雅的迁移工具。
- 不过他们已经朝这个方向前进几步了,根据 PEP 518,Python 的构建依赖项被合并为 pyproject.toml 文件格式(取代了 setup.py, requirements.txt, setup.cfg, MANIFEST.in 以及最新加入的 Pipfile)
- 当然也不是没有办法,使用 poetry 赖管理工具,它能够很方便地将你所需要的依赖打包在一起。