pyrex学习笔记

[size=large]0.
easy_install pyrex

1.写pyrex文件
~/pyrex $ ls
__init__.py primes.pyx

~/pyrex $ cat primes.pyx
#coding:utf-8

#一个函数
def primes(int kmax):
cdef int n, k, i
cdef int p[1000]
result = []
if kmax > 1000:
kmax = 1000
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] <> 0:
i = i + 1
if i == k:
p[k] = n
k = k + 1
result.append(n)
n = n + 1
return result


#一种类型
"""
1.
Finalization method: __dealloc__
The counterpart to the __cinit__ method is the __dealloc__ method, which should perform the inverse of the __cinit__ method. Any C data structures that you allocated in your __cinit__ method should be freed in your __dealloc__ method.

2.
http://blog.donews.com/limodou/archive/2004/08.aspx?PageNumber=2
在 Python 中,在一个类定义中引用一个类方法,得到的是一个一般的函数对象。但在 pyrex 中得到的是一个未与类绑定的对象。这样导致的结果是通常使用的classmethod和staticmethod这样的用法在pyrex中不可用。例如,在Python中可以:

class spam:
def method(self):
...
method = classmethod(method)

但在 pyrex 中不能使用。你可以在类的外面定义这个方法,然后在类的定义中,将classmethod和staticmethod的结果赋给类的变量。如:

def Spam_method(cls):
...
class spam:
method = classmethod(Spam_method)
"""
cdef class Spam:

cdef int amount

def __cinit__(self):
self.amount = 0

def get_amount(self):
return self.amount

def set_amount(self, new_amount):
self.amount = new_amount

def describe(self):
print self.amount, "tons of spam!"

2.编译
pyrexc -r primes.pyx
生成了 primes.c
gcc -O2 -fPIC -shared -o primes.so -I/home/zuroc/include/python2.6 -L/home/zuroc/lib primes.c

3.运行
>>> import primes
>>> primes.primes(10)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
>>> spam=primes.Spam()
>>> spam.get_amount()
0

4.封装现有c函数

"""
http://blog.donews.com/limodou/archive/2004/08.aspx?PageNumber=2

cdef extern from "spam.h":
int spam_counter
void order_spam(int tons)

这个cdef extern from子句做了三件事:

1. 它告诉pyrex设置一个#include语句在生成的C代码中,使用指定的头文件
2. 它阻止pyrex对下面的代码缩近块中存在的声明生成C的声明代码
3. 它会认为代码块中所有的声明都是以cdef extern开始的

也就是说,pyrex本身不会去读取指定的头文件,自动分析哪些在头文件中有声明,这个工作需要你去做,你要指定哪些变量或函数已经在头文件中声明了(就是在代码块中进行原型的声明),告诉pyrex不要再为这些变量或函数产生声明C代码了。

每一个pyrex模块都为Python和C名字提供一个模块级的名字空间。不过当你想要封装一些外部的C函数,并以相同的名字提供给用户Python函数时,这样就不方便了。

一种方法是使用C名字规范(c name specification, 就是在一个名字后面跟着一个字符串)来对一个C函数给出不同的python和C名字。例如:

cdef extern void c_eject_tomto "eject_tomato" (float speed)

...........


通过使用public关键字,可以使得在pyrex内部声明的C变量和函数被外部的C代码(或pyrex模块)使用,例如:
cdef public int spam #公共变量声明


"""
另外一种是

Using cimport to resolve naming conflicts

The cimport mechanism provides a clean and simple way to solve the problem of wrapping external C functions with Python functions of the same name. All you need to do is put the extern C declarations into a .pxd file for an imaginary module, and cimport that module. You can then refer to the C functions by qualifying them with the name of the module. Here's an example:

c_lunch.pxd
cdef extern from "lunch.h":
void eject_tomato(float) cimport c_lunch

lunch.pyx
def eject_tomato(float speed):
c_lunch.eject_tomato(speed)

You don't need any c_lunch.pyx file, because the only things defined in c_lunch.pxd are extern C entities. There won't be any actual c_lunch module at run time, but that doesn't matter; the c_lunch.pxd file has done its job of providing an additional namespace at compile time.[/size]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值