当前位置:网站首页>Cython入门
Cython入门
2022-06-26 05:48:00 【Wanderer001】
setup这一年也是遇到了很多次,随着python编程学习的不断深度对于python的了解也不断在增加,这里做一次简单的小节。
相关工具:distutils,cython
1.Cython简介
我们平时使用的python,又叫CPython,因为他是用C语言写的,一般来说,我们的python源代码(.py沃森件),首先编译成字节码(.pyc文件),然后将.pyc文件放在python虚拟机上运行,这里的python虚拟机就是所谓的“python解释器”。总而言之,纯python代码的运行速度介于传统的编译语言和传统的解释语言之间。
2.1什么是字节码?
字节码在python虚拟机程序里对应的是PyCodeObject对象; .pyc文件是字节码在磁盘上的表现形式。
每一个以py结尾的python源代码文件都是模块,其中那个启动后能够运行整个程序的文件叫顶层文件。而顶层文件导入其他模块(文件),必须找到文件然后将其编译成字节码,并且运行字节码。
导入文件时编译的字节码会自动保存,同时保存的还有时间戳。如果同时存在.py和.pyc,python会使用.pyc运行,如果.pyc的编译时间早于.py的时间,则重新编译.py,并更新.pyc文件。
如果python无法在机器上写入字节码,程序仍然可以工作,字节码会在内存中生成并在程序结束时丢弃掉。(严格而讲,只有文件导入的情况下字节码才会保存,并不是对顶层文件)。
如果想生成test.pyc,我们可以使用python内置模块py_compile来编译。也可以执行命令 python -m test.py 这样,就生成了test.pyc。
typedef struct {
PyObject_HEAD
int co_argcount; /* 位置参数个数 */
int co_nlocals; /* 局部变量个数 */
int co_stacksize; /* 栈大小 */
int co_flags;
PyObject *co_code; /* 字节码指令序列 */
PyObject *co_consts; /* 所有常量集合 */
PyObject *co_names; /* 所有符号名称集合 */
PyObject *co_varnames; /* 局部变量名称集合 */
PyObject *co_freevars; /* 闭包用的变量名集合 */
PyObject *co_cellvars; /* 内部嵌套函数引用的变量名集合 */
/* The rest doesn’t count for hash/cmp */
PyObject *co_filename; /* 代码所在文件名 */
PyObject *co_name; /* 模块名|函数名|类名 */
int co_firstlineno; /* 代码块在文件中的起始行号 */
PyObject *co_lnotab; /* 字节码指令和行号的对应关系 */
void *co_zombieframe; /* for optimization only (see frameobject.c) */
} PyCodeObject;2.2执行字节码?
Python虚拟机的原理就是模拟可执行程序再X86机器上的运行,X86的运行时栈帧如下图:当发生函数调用时,创建新的栈帧,对应Python的实现就是PyFrameObject对象。PyFrameObject对象创建程序运行时的动态信息,即执行环境,相关源码大致如下:
typedef struct _frame{
PyObject_VAR_HEAD //"运行时栈"的大小是不确定的
struct _frame *f_back; //执行环境链上的前一个frame,很多个PyFrameObject连接起来形成执行环境链表
PyCodeObject *f_code; //PyCodeObject 对象,这个frame就是这个PyCodeObject对象的上下文环境
PyObject *f_builtins; //builtin名字空间
PyObject *f_globals; //global名字空间
PyObject *f_locals; //local名字空间
PyObject **f_valuestack; //"运行时栈"的栈底位置
PyObject **f_stacktop; //"运行时栈"的栈顶位置
//...
int f_lasti; //上一条字节码指令在f_code中的偏移位置
int f_lineno; //当前字节码对应的源代码行
//...
//动态内存,维护(局部变量+cell对象集合+free对象集合+运行时栈)所需要的空间
PyObject *f_localsplus[1];
} PyFrameObject;每一个 PyFrameObject对象都维护了一个 PyCodeObject对象,这表明每一个 PyFrameObject中的动态内存空间对象都和源代码中的一段Code相对应。
2.2什么是Cython?
Cython是Python语言的扩展模块,他的目的在于称为python语言的超集(superset),为python提供高级的,面向对象的,函数式的和动态的编程。他的主要功能是支持(可选)部分静态类型的声明作为Cython语言的一部分。这样cython的源代码就可以被转化为优化过的C/C++代码,然后可以将这些代码编程称为python的扩展模块。Cython代码在CPython运行时环境中执行,但是以编译的C的速度执行,并且能够直接调用C库。同时,它保留了Python源代码的原始接口,这使得它可以直接从Python代码中使用。
2.3构建Cython
Cython代码必须编译,具体包括两步:
第一步,将A.pyx文件用Cython编译到一个.c文件中,其中含有python扩展模块的代码
第二步,将.c文件编译成.so文件(Windows下为.pyd文件),该文件可以 直接import进入Python session。Distutils或setuptools负责这部分。虽然Cython可以在某些情况下为你调用它们。
具体实例,在faser rcnn中,bbox_overlaps函数就行用cython写的。

具体构建Cython的几种方法:
1.写一个distutils / setuptools setup.py。
setyp.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("helloworld.pyx")
)命令行:
$ python setup.py build_ext --inplace2.使用Pyximport,导入Cython .pyx文件就像它们是.py文件一样(使用distutils在后台编译和构建)。这种方法比编写一个setup.py容易一些。但不是很灵活,比如,您需要某些编译选项。(其实,没有学习编译原理的我不需要哪些编译选项,显然这种方法是极好的)。但是,我的电脑在使用这种方法的时候,失败了,可能是VS环境的原因吧,所以我采用了第一种方法,直接编译了一个pyd文件使用。
import pyximport; pyximport.install()
import helloworld# Hello World3.Jupyter notebook允许内联Cython代码。这是开始编写Cython代码并运行它的最简单方法。
2.distutils简介
除了Cython中使用到setup.py,编写python的第三方库,也是要编写setup.py的。其实如果我们下载过一些第三库的源代码文件,打开之后一般就会有一个setup.py,执行python setup.py install 就可以安装这个库了。setup.py 如何编写内容很多,可以参考官方文档:https://wiki.python.org/moin/Distutils/Tutorial?highlight=%28setup.py%29。一个典型的setup.py的写法如下(参考自官方文档):
文件结构为: top |-- package | |-- __init__.py # 空的 | |-- module.py # 这个package中的模块文件 | `-- things | |-- cross.png | |-- fplogo.png | `-- tick.png |-- README `-- setup.py
setup.py:
from distutils.core import setup
#This is a list of files to install, and where
#(relative to the 'root' dir, where setup.py is)
#You could be more specific.
files = ["things/*"]
setup(name = "appname",
version = "100",
description = "yadda yadda",
author = "myself and I",
author_email = "[email protected]",
url = "whatever",
#Name the folder where your packages live:
#(If you have other packages (dirs) or modules (py files) then
#put them into the package directory - they will be found
#recursively.)
packages = ['package'],
#'package' package must contain files (see list above)
#I called the package 'package' thus cleverly confusing the whole issue...
#This dict maps the package name =to=> directories
#It says, package *needs* these files.
package_data = {'package' : files },
#'runner' is in the root.
scripts = ["runner"],
long_description = """Really long text here."""
#
#This next part it for the Cheese Shop, look a little down the page.
#classifiers = []
) Making the installation tarball
python setup.py sdist我的编译过程:
setup.py:
import sys
import numpy as np
A=sys.path.insert(0, "..")
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext
# ext_module = cythonize("TestOMP.pyx")
ext_module = Extension(
"bbox",
["bbox.pyx"],
extra_compile_args=["/openmp"],
extra_link_args=["/openmp"],
)
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [ext_module],
#注意这一句一定要有,不然只编译成C代码,无法编译成pyd文件
include_dirs=[np.get_include()]
) 
边栏推荐
- Unicloud cloud development obtains applet user openid
- The use of loops in SQL syntax
- 类和对象的学习
- Machine learning 05: nonlinear support vector machines
- 操作符的优先级、结合性、是否控制求值顺序【详解】
- LeetCode_ Binary search tree_ Simple_ 108. convert an ordered array to a binary search tree
- Last flight
- MySQL database-01 database overview
- 【C語言】深度剖析數據在內存中的存儲
- Consul服务注册与发现
猜你喜欢

pytorch(环境、tensorboard、transforms、torchvision、dataloader)

C generic speed

When was the autowiredannotationbeanpostprocessor instantiated?

【C語言】深度剖析數據在內存中的存儲

The purpose of writing programs is to solve problems

REUSE_ ALV_ GRID_ Display event implementation (data_changed)

Household accounting procedures (the second edition includes a cycle)
![Operator priority, associativity, and whether to control the evaluation order [detailed explanation]](/img/c3/a646a7c7cb82e00746923f7b023058.jpg)
Operator priority, associativity, and whether to control the evaluation order [detailed explanation]

DOM document

uniCloud云开发获取小程序用户openid
随机推荐
About XXX management system (version C)
The purpose of writing programs is to solve problems
Yamaha robot splits visual strings
421- binary tree (226. reversed binary tree, 101. symmetric binary tree, 104. maximum depth of binary tree, 222. number of nodes of complete binary tree)
电商借助小程序技术发力寻找增长突破口
SQL Server 函数
冒泡排序(Bubble Sort)
Gram matrix
最后一次飞翔
Ribbon负载均衡服务调用
Kolla ansible deploy openstack Yoga version
Something about MariaDB
SDN based DDoS attack mitigation
There are applications related to web network request API in MATLAB (under update)
Soft power and hard power in program development
从新东方直播来探究下小程序音视频通话及互动直播
Cyclic displacement
【C语言】深度剖析数据在内存中的存储
Feelings of virtual project failure
Daily production training report (15)