Python编译成C
参考文章:https://blog.csdn.net/sinat_28375239/article/details/108265559
参考文章:https://blog.csdn.net/fu6543210/article/details/90770794
参考文章:https://iowiki.com/jython/jython_overview.html
参考文章:https://blog.csdn.net/weixin_45530440/article/details/123531932
参考文章:https://zhuanlan.zhihu.com/p/454377119
python 是一门解释型语言,效率与编译型语言比效率较低;python 解释器使用最广泛的是Cpython
使用 C 语言开发的 python 解释器;当我们对效率具有一定要求的时候可以将python
代码编译成为 C;
1.解释器的介绍
Python 解释器最常见的是Cpython, 之所以使用CPython
这个词,是因为Python还有一些其它的实现,比如Jython
,就是Java版的Python,还有烧脑的PyPy
,使用 Python 再把 Python 实现了一遍。由于整个 Python 语言从规范到解释器都是开源的,所以理论上,只要水平够高,任何人都可以编写 Python 解释器来执行 Python 代码(当然难度很大)。事实上,确实存在多种 Python 解释器;
1.1 Cpython
CPython 是特指 C 语言实现的Python,就是原汁原味的Python。
当我们编写 python 代码的时候,我们得到以.py
为扩展名的文件,运行代码的时候是需要 Python 解释器去解释执行.py
文件。
当我们从 Python 官方网站下载并安装好 Python 3.x后,我们就直接获得了一个官方版本的解释器:CPython。这个解释器是用C语言开发的,所以叫CPython。在命令行下运行 python 就是启动CPython解释器。CPython是使用最广的Python解释器。
Cython 语言是 Python 的一个超集,编译成C语言,产生的性能提升可以从几个百分点到几个数量级,具体取决于手头的任务。 对于受Python原生对象类型约束的工作,加速将不会很大。 但是对于数值操作,或任何不涉及 Python 自身内部的操作,收益可能是巨大的。
1.2 Jpython
Jython(原 JPython),是一个用 Java 语言写的 Python 解释器。Jython 程序可以和 Java 无缝集成。除了一些标准模块,Jython 使用 Java 的模块。
Jython 是 Python 编程语言的 JVM 实现。 它旨在在Java平台上运行。 Jython程序可以导入和使用任何Java类。 就像Java一样,Jython程序编译为bytecode 。 其中一个主要优点是用Python设计的用户界面可以使用AWT , Swing或SWT Package GUI元素。
以下是Python和Jython之间的区别 :
- Python 的参考实现,称为 CPython,是用 C 语言编写的。 另一方面,Jython 完全用 Java 编写,是一个 JVM 实现。
- 标准 Python 可在多个平台上使用。 Jython 适用于安装了 JVM 的任何平台。
- 标准 Python 代码编译为.pyc文件,而 Jython 程序编译为.class文件。
- Python 扩展可以用 C 语言编写。 Jython 的扩展是用 Java 编写的。
- Jython 本质上是真正的多线程。 然而,Python使用Global Interpreter Lock (GIL)机制来实现此目的。
- 两种实现都有不同的垃圾收集机制。
1.3 pypy
Pypy 是用 Python 自身实现的解释器。针对 CPython 的缺点进行了各方面的改良,性能得到很大的提升。最重要的一点就是Pypy集成了JIT(即时编译)。但是,Pypy无法支持官方的C/Python API,导致无法使用例如Numpy,Scipy等重要的第三方库。这也是现在Pypy没有被广泛使用的原因。
PyPy 使用了JIT(即时编译)技术,混合了动态编译和静态编译的特性,仍然是一句一句编译源代码,但是会将翻译过的代码缓存起来以降低性能损耗。相对于静态编译代码,即时编译的代码可以处理延迟绑定并增强安全性。绝大部分 Python 代码都可以在 PyPy 下运行,但是 PyPy 和 CPython 有一些是不同的。
2.编译Python到C
Python 代码可以直接调用 C 模块。这些 C 模块可以是通用的 C 库或专门为 Python 工作的库。Cython 生成第二种类型的模块:与Python 内部对话的 C 库,可以与现有的 Python 代码绑定在一起。
Cython 代码在设计上看起来很像 Python 代码。如果你给 Cython 编译器提供了一个Python程序,它将会按原样接受它,但是 Cython 的原生加速器都不会起作用。但是如果你用 Cython 的特殊语法来修饰 Python 代码,那么 Cython 就可以用快速的 C 代替慢的 Python 对象。
2.1 python 文件编译为C文件
-
安装
pip install cpython pip install cython
-
使用
创建
.pyx
文件,将 python 的代码写入文件中;创建setup.py
文件,这两个文件都在同一文件夹下面;# code.pyx def main(): print("+"*13,"执行开始","+"*13) print("666666666666666") print("+"*13,"执行结束","+"*13) main()
编写
setup.py
# setup.py from setuptools import setup from Cython.Build import cythonize # 编译 pyx 文件; setup(ext_modules=cythonize('code.pyx'))
在终端中执行该文件
python setup.py build_ext --inplace
执行完成之后会在同级目录下面产生
code.c
的文件,unix
系统可能会产生的是.so
;用参数
build_ext
运行setup.py
时,Cython会查找cythonfn.pyx并构建code.so
--inplace
参数让 Cython 在当前目录中构建编译模块,而不是在一个独立的构建目录中。在构建完成后,会得到中间文件cythonfn.c
和code.so
。 -
.pyx
介绍pyx 文件是由 Cython 编程语言 编写 而成的 Python 扩展模块源代码文件。
.pyx
文件要想被 python 语言直接识别,必须先被编译成.c
文件,再编译成.pyd
或.so
文件,才可作为模块import直接导入使用。
2.2 多文件编译
把一个目录下所有python源文件编译pyc;这种形式的编译是直接编译成为二进制文件,与C 不同;
一般来说,我们的工程都是在一个目录下的,一般不会说仅仅编译一个py文件而已,而是需要把整个文件夹下的py文件都编译为pyc文件,python又为了我们提供了另一个模块:compileall 。使用方法如下:
python -m compileall ./路径
编译完成后如果想要直接运行Pyc文件注意两点:要把pyc
文件从pycache
目录中移动出来,放到py
文件对应的位置
修改pyc
文件名,生成的pyc
文件的文件名一般为.cpython-36.pyc。pyc 文件可以和 py 文件一样用 import 导入,但是在此之前需要将pyc 文件重命名;
# 例如对 model.py 生成的pyc文件为 model.cpython-36.pyc
# 如果现在想导入model.cpython-36.pyc,直接用
import model
# >>> 会报错ImportError: No module named 'model'
# 需要将model.cpython-36.pyc重命名为model.pyc
注意:
compileall.compile_path(skip_curdir=True, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1)
字节编译沿 sys.path 找到的所有.py
文件。如果所有文件都已成功编译,则返回true
值,否则返回false
值。
如果 skip_curdir
为true
(默认值),则当前目录不包括在搜索中。所有其他参数传递到 compile_dir()
函数。注意,与其他编译函数不同,maxlevels 默认为 0。
pyc文件就是 Python 程序编译后得到的字节码文件 (py->pyc).
标签:文件,解释器,Python,编译成,py,编译,pyc From: https://www.cnblogs.com/Blogwj123/p/17016291.html