2 基
本使用
Cython基于pyrex,但是拥有更多功能和优化。用来写Python的C扩展的,并生成有效的C代码。写出的文件扩展名是 ".pyx"
,已经可以算作一种语言了。
一个简单的加法函数( addtest.pyx
):
def addtest(a,b):
cdef float c=a+b
return c
编译和生成动态库:
cython addtest.pyx
gcc -c -fPIC -I/usr/include/python2.5 addtest.c
gcc -shared addtest.o -o addtest.so
使用:
$ python
>>> import addtest
>>> addtest(1,2)
3.0
构建Cython代码的方式:
- 使用 setup.py
,常用
- 使用pyximport导入 ".pyx" 文件
- 运行cython命令编译出.c文件后再编译成.so文件
- 使用Sage
使用 setup.py
方式,例如一个 hello.pyx
文件,编写的 setup.py
如下:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules=[Extension('hello',['hello.pyx'])]
setup(
name='Hello world app',
cmdclass={'build_ext':build_ext},
ext_modules=ext_modules
)
构建使用命令 python
setup.py
build_ext
--inplace
。
Cython提高速度的主要原因是使用静态类型。可以在任何参数前直接使用C的类型定义。函数内的话要加"cdef"前缀。如:
def f(double x):
cdef double ret
ret=x**2-x
return ret
仅仅使用Cython编译纯Python代码可以提高35%的性能,几乎全部使用静态类型以后提高4倍。
C风格函数声明,"except? -2"表示返回-2时就是出错了。不过"except *"是肯定安全的。如:
cdef double f(double) except? -2:
return x**2-x
使用cpdef时,这个函数就可以同时被C和Python调用了。当使用了C函数时,因为避开了昂贵的函数调用,旺旺可以提高150倍的速度。
不要过度优化,一步步的优化并且查看profile。使用"cython -a"参数可以查看HTML报告。
3 调
用其他C库
3.1 简
单例子
导入"math.h"中的 sin()
函数并使用:
cdef extern from "math.h":
double sin(double)
cdef double f(double x):
return sin(x*x)
Cython不会去扫描头文件,所以自己必须再声明一遍。下面是使用时必须连接上其他库的 setup.py
文件:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules=[
Extension('demo',['demo.pyx',],libraries=['m',])
]
setup(
name='Demos',
cmdclass={'build_ext':build_ext},
ext_modules=ext_modules,
)
同理可以使用任何动态或静态编译的库。
3.2 重
新定义外部C库的定义
一段C代码,头文件中的类型定义与函数声明:
typedef struct _Queue Queue;
typedef void *QueueValue;
Queue *queue_new(void);
void queue_free(Queue *queue);
int queue_push_head(Queue *queue, QueueValue data);
QueueValue queue_pop_head(Queue *queue);
QueueValue queue_peek_head(Queue *queue);
int queue_push_tail(Queue *queue, QueueValue data);
QueueValue queue_pop_tail(Queue *queue);
QueueValue queue_peek_tail(Queue *queue);
int queue_is_empty(Queue *queue);
对应的Cython定义,写入一个".pxd"文件中:
cdef extern from "libcalg/queue.h":
ctypedef struct Queue:
pass
ctypedef void* QueueValue
Queue* new_queue()
void queue_free(Queue* queue)
int queue_push_head(Queue* queue, QueueValue data)
QueueValue queue_pop_head(Queue* queue)
QueueValue queue_peek_head(Queue* queue)
int queue_push_tail(Queue* queue, QueueValue data)
QueueValue queue_pop_tail(Queue* queue)
QueueValue queue_peek_tail(Queue* queue)
bint queue_is_empty(Queue* queue)
大部分时候这种声明与头文件几乎是一样的,你可以直接拷贝过来。唯一的区别在最后一行,C函数的返回值其实是布尔值,所以用bint类型会转换成
Python的布尔值。
这里可以不关心结构体的内容,而只是用它的名字。
4 类
定义
一个类的例子:
cimport cqueue
cimport python_exc
cdef class Queue:
cdef cqueue.Queue_c_queue
def __cinit__(self):
self._c_queue=cqueue.new_queue()
这里的构造函数是 __cinit__()
而不是 __init__()
。虽然 __init__()
依然有效,但是并不确保一定会运行(比如子类忘了调用基类的构造函数)。因为未初始化的指针经常导致Python挂掉而没有任何提示,所以 __cinit__()
总是会在初始化时调用。不过其被调用时,对象尚未构造完成,所以除了cdef字段以外,避免其他操作。如果要给 __cinit__()
构造和函数加参数,必须与 __init__()
的匹配。
构造函数初始化资源时记得看看返回的资源是否是有效的。如果无效可以抛出错误。Cython提供了内存不足异常,如下:
def __cinit__(self):
self._c_queue=cqueue.new_queue()
if self._c_queue is NULL:
python_exc.PyErr_NoMemory()
Cython提供的析构函数,仅在建立成功内部对象时释放内部对象:
def __dealloc__(self):
if self._c_queue is not NULL:
cqueue.queue_free(self._c_queue)
将数据以通用指针方式进入,和返回时的强制类型转换:
cdef append(self,int value):
cqueue.queue_push_tail(self._c_queue,<void*>value)
cdef int pop(self):
return <int>cqueue.queue_pop_head(self._c_queue)
Cython除了支持普通Python类以外,还支持扩展类型,使用"cdef
class"定义。在内存占用和效率上更好。因为使用C结构体存储字段和方法,而不是Python字典。所以可以存储任意C字段类型,而不是其
Python包装。访问时也是直接访问C的值,而不是通过字典查找。
普通的Python类可以继承自cdef类,但是反之则不行。Cython需要知道完整的继承层次来定义C结构体,并且严格限制单继承。不过普通
Python类可以继承任一数量的Python类和扩展类型,无论在Python中还是在Cython代码中。
5 与
Python交互
如果Cython调用Python函数失败,则直接返回NULL,而不是异常对象。
如果一个函数既有可能返回NULL,也有可能返回0,则处理起来就比较麻烦。Python C API的做法是 PyErr_Occurred()
函数。不过这种方式有性能损耗。在Cython中你可以自己指定哪个返回值代表错误,所以环境只要检查这个返回值即可。其他所有值都回无损耗的被接受。
在函数定义时指定except子句,则仅在函数返回该值时检查是否需要抛出异常。这样同一个函数返回0和返回0同时返回错误就可以区分开。例子:
cdef int pop(self) except? 0:
#...
类中的 cdef 定义C方法,而 cpdef 可以同时定义C方法和Python方法。
相关推荐
"cython_bbox-0.1.3" 是一个软件包,它主要涉及到两个技术领域:`pip` 和 `Cython`。首先,我们来详细了解一下这两个概念。...它的使用可以提高代码执行效率,尤其是对于需要处理大量边界框数据的应用来说。
- **高性能网络服务**:对于需要快速响应的网络应用,Cython可以加速I/O操作和数据处理。 - **游戏开发**:在游戏逻辑和物理引擎等对速度有苛刻要求的部分,Cython可以提供比纯Python更好的性能。 - **机器学习库*...
**Cython教程** Cython是一种混合静态类型和动态类型的编程语言,它将Python的易读性和灵活性与C的高效性能相结合。Cython是Python的一个扩展,它的目标是为Python程序员提供一种方式,通过简单的语法糖来编译成C...
[Packt Publishing] Cython 编程学习教程 (英文版) [Packt Publishing] Learning Cython Programming (E-Book) ☆ 图书概要:☆ Expand your existing legacy applications in C using Python Overview Extend ...
Cython 文件在 window 与 linux 下的编译指导 Cython 文件在 window 与 linux 下的编译指导是指在不同的操作系统平台上编译 Cython 文件的指导。Cython 是一种高级语言,可以将 Python 代码编译成 C 代码,然后再...
在IT行业中,优化Python代码性能是一项常见的需求,而Cython是一种解决方案,它允许开发者使用Python语法来编写接近原生速度的C/C++代码。本文将详细介绍如何使用Cython来封装C++代码,以便在Python环境中高效地运行...
《Learning Cython Programming》一书由Philip Herron撰写,深入探讨了如何利用Cython来优化现有Python应用,特别是在处理遗留C代码时。本书不仅适用于Python开发者,也适合那些希望在Python环境中利用C语言性能优势...
Cython作为一个Python库,它的主要功能和应用场景包括: 1. **性能优化**:对于那些性能要求高的代码段,Cython允许开发人员使用静态类型,将Python代码转换为C扩展,从而提高运行速度。 2. **接口绑定**:Cython...
它主要面向那些需要性能优化的场景,特别是对于那些对性能有着严苛要求的Python应用程序,Cython可以作为一种重要的优化手段。此外,Cython也使得Python可以更好地与现有的C语言代码库和第三方C库集成,从而拓宽了...
**Cython入门详解** Cython是一种混合静态类型的Python方言,旨在提高Python代码的运行效率,尤其是在科学计算和数值处理领域。它允许开发者使用类似于Python的语法编写代码,但同时引入了类型声明,使得编译后的...
Cython是一种编程语言,它是Python的一个扩展,旨在提高Python代码的执行速度。它允许开发者将Python代码转换为C语言,从而可以直接编译成高效的机器代码。Cython 0.23 是一个较早的版本,它在开发科学计算库如...
Cython是一种混合编程语言,它是Python的一个扩展,旨在提高Python代码的执行速度。Cython-0.23.3.tar.gz 是Cython的0.23.3版本的源码包,通常用于开发者进行编译和安装。这个压缩包包含了构建、安装Cython所需的...
Cython-3.0.10-cp38-cp38-win_amd64.whl 是一个在 Windows 平台上用于 Python 3.8 版本的 Cython 安装包。Cython 是一种编程语言,主要用于将 Python 代码转换为 C/C++ 代码以提高性能。它允许开发者在 Python 中...
**cp27m** 是Python的 ABI(应用程序二进制接口)标记,表明这是一个使用了小端存储模式(little-endian)的Python 2.7版本,并且包含了一些Python的微优化。ABI是不同软件组件之间接口的规范,确保它们可以正确地...
此为适用于linux系统python3.6的cython安装包,版本为0.29
在实际应用中,当需要大量处理`OrderedDict`,尤其是在性能敏感的场景下,使用`Cython-OrderedDict`这样的优化实现可以显著提升程序的运行速度。不过,需要注意的是,虽然`Cython`可以提供性能提升,但也会增加代码...
由python、C、Cython实现的二叉树树源码。树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样。树结构在客观世界中广泛存在,如人类社会的...