注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

蜻蜓点水 举重若轻

君子终日乾乾

 
 
 

日志

 
 

用 Python 写自己的 C Module  

2009-09-10 11:54:28|  分类: Python |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

本文说一下如何把 python 翻译成如假包换的 c 源码, 然后编译成一个 python module。据官方博客称性能接近或超过 c。用到了 pypy —— python 史上最大的玩具。

先写个 python 源码文件, 待会编译出来:

# hello.py 文件

def hello(a, b):
print a, b
return 'OK'

def target(drv, args):
return hello, [str, str]


先测试通过:

>>> import hello
>>> result = hello.hello('hello', 'world!')
hello world!
>>> print result
OK


翻译成 c 并编译:

    $ pypy/translator/goal/translate.py --batch hello.py

生成的目标在, /tmp/usession-dist-USERNAME/testing_1/testing_1.so 。

    $ mv /tmp/usession-dist-USERNAME/testing_1/testing_1.so _hello.so

也可以写个自动化脚本编译完自动拷贝出去, 生成 testing_1.so 的目录位置在 driver.cbuider 对象里。可以参考 translate.py 写一个自己的编译平台 (哦, 一个玩笑)。

我们得到了 _hello.so 。里面有这么一个接口, 可以想见 python 调用起来很方便 (c 定义):

    PyObject *pypy_g_pyfn_hello(PyObject *l_a_0, PyObject *l_b_0);

至少在 pypy-1.1.0 里是这样的, 以后就不一定了。


测试。先写个 _hello.so 的 python wrapper:

# hello.py 文件, _hello.so 的 python wrapper
from ctypes import *
_hello = PyDLL('/PATH/TO/_hello.so')
_hello.RPython_StartupCode()
hello = _hello.pypy_g_pyfn_hello
hello.restype = py_object
hello.argtypes = [py_object, py_object]


测试通过:

>>> import hello
>>> result = hello.hello('hello', 'world!')
hello world!
>>> print result
OK


这样, 我们就可以用 rpython 来写可编译执行的 python c module 了 (这是 c 后端, 据称在 cli 和 jvm 上能做的事情更多一些)。然后好处是, 你的模块可以同时兼容 python2、python3、pypy 了。进一步他是个 c lib (pypy 会导出 c 接口), 其实在任何语言平台上都是可以用的。

不过, 这显然不是标准的 pypy 应用, 事实上我们应该用 pypy 的 MixedModule 来写。不过可惜的是 MixedModule 编译到 python c module 的功能已经在 pypy-1.1.0 取消了。pypy 团队在事后就此事和广大 pypy 用户进行了讨论, 取消该功能是否是个好主意 (在已经取消的前提下)。官方觉得, 还是专注于把 jit 搞好吧, 其他炫的东西先放一放, 毕竟 jit 搞定了, 你就不再需要什么 python c module 了。总之, 你需要等很久, 无聊的话, 像这篇文章这样玩一下也不错 。

PS: 喜欢把 python 编译执行的朋友, 可以试一下 Cython 和 ShedSkin, 他们是专门为这个目标设计的。

  评论这张
 
阅读(8731)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017