cython教程
.写测试代码: zhouhh@zhouhh-home:~$ vi test.pyx [python] view plaincopy def sayhello(char* str): if str == None: print 'hello world' else: print str .编译成C语言 zhouhh@zhouhh-home:~$ cython test.pyx zhouhh@zhouhh-home:~$ ls test.c test.c test.c是由cython通过 test.pyx生成的。 . gcc编译成.o文件 直接执行gcc会出错,必须包含python目录。 zhouhh@zhouhh-home:~$ gcc test.c test.c::: error: Python.h: 没有该文件或目录 test.c::: error: structmember.h: 没有该文件或目录 test.c::: error: #error Python headers needed to compile C extensions, please install development version of Python. ... zhouhh@zhouhh-home:~$ gcc -c -fPIC -I/usr/include/python2. test.c -fPIC表示编译成共享库,-I后跟include的路径。 .生成共享库 zhouhh@zhouhh-home:~$ gcc -shared test.o -o test.so .在python中引用共享库 zhouhh@zhouhh-home:~$ vi test.py import test test.sayhello('ni hao') .执行 zhouhh@zhouhh-home:~$ python test.py ni hao .疑问: 不知怎么穿NULL指针给函数参数。 .参考: http://www.cython.org/ http://blog.csdn.net/lanphaday/archive/2009/09/17/4561611.aspx
一种为Python写C扩展的方式,尝试一下。 参考文献: [r] 官方主页: http://www.cython.org/ [r] Cython三分钟入门: http://blog.csdn.net/lanphaday/archive/2009/09/17/4561611.aspx [u] A quick Cython introduction: http://www.perrygeo.net/wordpress/?p=116 其实就是上文的原文 [i] Cython's Documentation: http://docs.cython.org/ 看到"Extensioin types" 基 本使用 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. addtest.c gcc -shared addtest.o -o addtest.so 使用: $ python >>> import addtest >>> addtest(,) 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**-x return ret 仅仅使用Cython编译纯Python代码可以提高35%的性能,几乎全部使用静态类型以后提高4倍。 C风格函数声明,"except? -2"表示返回-2时就是出错了。不过"except *"是肯定安全的。如: cdef : -x 使用cpdef时,这个函数就可以同时被C和Python调用了。当使用了C函数时,因为避开了昂贵的函数调用,旺旺可以提高150倍的速度。 不要过度优化,一步步的优化并且查看profile。使用"cython -a"参数可以查看HTML报告。 调 用其他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的布尔值。 这里可以不关心结构体的内容,而只是用它的名字。 类 定义 一个类的例子: 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代码中。 与 Python交互 如果Cython调用Python函数失败,则直接返回NULL,而不是异常对象。 如果一个函数既有可能返回NULL,也有可能返回0,则处理起来就比较麻烦。Python C API的做法是 PyErr_Occurred() 函数。不过这种方式有性能损耗。在Cython中你可以自己指定哪个返回值代表错误,所以环境只要检查这个返回值即可。其他所有值都回无损耗的被接受。 在函数定义时指定except子句,则仅在函数返回该值时检查是否需要抛出异常。这样同一个函数返回0和返回0同时返回错误就可以区分开。例子: cdef : #... 类中的 cdef 定义C方法,而 cpdef 可以同时定义C方法和Python方法
举个例子: # hello.pyx def say_hello_to(name): print("Hello %s!" % name) # 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 在Python里调用: from hello import say_hello_to say_hello_to(" world ")
cython教程的更多相关文章
- Cython:基础教程(1) 语法
1 变量定义 http://docs.cython.org/src/reference/language_basics.html http://blog.csdn.net/i2cbus/article ...
- Cython: 快速入门
1. Cython是什么? 它是一个用来快速生成Python扩展模块(extention module)的工具,语法是Python和c的混血.在Cython,C里的类型,如int,float,long ...
- Ubuntu16.04+cuda8.0rc+opencv3.1.0+caffe+Theano+torch7搭建教程
https://blog.csdn.net/jywowaa/article/details/52263711 学习中用到深度学习的框架,需要搭建caffe.theano和torch框架.经过一个月的不 ...
- Python Kivy 中文教程:安装(Windows)
Kivy 是一套用于跨平台快速应用开发的开源框架,只需编写一套代码,便可运行于各大桌面及移动平台上(包括 Linux, Windows, OS X, Android, iOS, 以及 Raspberr ...
- opencv-python教程学习系列9-程序性能检测及优化
前言 opencv-python教程学习系列记录学习python-opencv过程的点滴,本文主要介绍程序性能检测及优化,坚持学习,共同进步. 系列教程参照OpenCV-Python中文教程: 系统环 ...
- Ubuntu16.04+Cuda8.0+1080ti+caffe+免OpenCV3.2.0+faster-rCNN教程
一.事先声明:1.Ubuntu版本:Ubuntu使用的是16.04.而不是16.04.1或16.04.2,这三个是有区别的.笔者曾有过这样的经历,Git上一个SLAM地图构建程序在Ubuntu14.0 ...
- Faster R-CNN教程
Faster R-CNN教程 最后更新日期:2016年4月29日 本教程主要基于python版本的faster R-CNN,因为python layer的使用,这个版本会比matlab的版本速度慢10 ...
- mmdetection安装教程
如果官方教程不行再参考我的吧,我的环境如下: ubuntu cuda10 cudnn7.5 步骤: 1.使用conda创建一个虚拟环境 conda create -n mmdetection pyth ...
- windows上安装Anaconda和python的教程详解
一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...
随机推荐
- SQL Server数据库连接字符串整理
1.sql验证方式的 Data Source=数据源;Initial Catalog= 数据库名;UserId=sql登录账号;Password=密码; Eg: Data Source=.;Initi ...
- 单选,复选操作div,显示隐藏
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...
- codeforces 589F. Gourmet and Banquet 二分+网络流
题目链接 给你n种菜, 每一种可以开始吃的时间不一样, 结束的时间也不一样. 求每种菜吃的时间都相同的最大的时间.时间的范围是0-10000. 看到这个题明显可以想到网络流, 但是时间的范围明显不允许 ...
- 字符串-06. IP地址转换
/* * Main.c * D6-字符串-06. IP地址转换 * Created on: 2014年8月19日 *******测试通过******** *转载:http://blog.csdn.ne ...
- windows7下,protel 99se元件库加载问题的解决方案
方法一:到C盘(系统盘),系统文件夹(c:\windows)下的ADVPCB99SE和ADVSch99SE文件先配置原理图,用本文打开ADVPCB99SE文件,在[Change Library Fil ...
- Pro/Engineer wildfire 5.0 野火版系列下载及安装方法
三.PTC Pro/Engineer wildfire 5.0 M030 野火版最新版 DVD 下载(多国语言) 1.野火下载站下载32&64位下载:[32位] http://down.pro ...
- QT完美转换特殊字符的大小写
Util::ShowMessage(QString::fromUtf8("ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØŒŠþÙÚÛÜÝŸ€")); Util::ShowMess ...
- OpenCV初探
一种基于OpenCV的PHP图像人脸识别技术 openCV是一个开源的用C/C++开发的计算机图形图像库,非常强大,研究资料很齐全.本文重点是介绍如何使用php来调用其中的局部的功能.人脸侦查技术只是 ...
- InnoDB引擎Myslq数据库数据恢复
首先祝愿看到这片文章的你永远不要有机会用到它... 本文指针对用InnoDB引擎的Mysql数据库的数据恢复,如果是其它引擎的Mysql或其它数据库请自行google... 如果有一天你手挫不小心删掉 ...
- ArcMAp对线要素进行平滑处(打断)
一:工具简单介绍 -- ArcMAp10.1的高级编辑工具中提供了对线/面要素进行概括/平滑处理的工具. 概括工具.平滑工具分别例如以下:(首先得开启编辑状态 --- 才干够对要素的属性进行更改).选 ...