1. python和cython是什么关系
Python和c的混血Cython作为一个Python的编译器,在科学计算方面很流行,用于提高Python的速度,通过OpenMPI库还可以进行吧并行计算。
2. 如何编译c文件中调用 cython
以下总结出几种在Python 中调用 C/C++ 代码的方法
--------------------------------------------------------------------
发现做便捷的是使用popen
from os import popen
popen('/home/pengyan/Downloads/VIC/sanxia/vicNl -g /home/pengyan/Downloads/VIC/sanxia/xings_global')
popen('/home/pengyan/Downloads/VIC/sanxia/rout /home/pengyan/Downloads/VIC/sanxia/xings_rout')
?? 目前还不会用python 切换文件目录
可以采用绝对路径,但是好像绝对路径时,计算速度变慢
-------------------------------------------------------------------
使用ctypes 模块调用 C 动态库
从Python2.5 开始, Python 开始提供 ctypes 模块来提供对 C 语言编译的动态库文件的调用。注意, 这里特指C 的动态库 ,用C++ 编译的动态库 ctypes 虽然能够加载,但调用时的函数名已经由于 C++ 的重载特性被加以修改,难以调用。 使用 ctypes 调用 C 动态库的好处在于不用进行额外的开发,可以直接使用编译好的动态库。 ctypes 提供了完整的 C 类型封装,也支持自定义类型,大大减少在调用过程中的工作量。 ctypes 的使用很简单,只需熟悉 python 封装与 C 中的对应关系即可。以下用一个简单的例子来说明:
from ctypes import * #导入ctypes模块
libc = cdll.LoadLibrary("libc.so.6") #加载libc动态库
str = c_char_p(' Hello World! ') #使用char *在ctypes中的对应封装c_char_p,相当于char* str=”Hello World!”
libc.printf(“yell: %s\n”, str ) #调用printf函数
ctypes的功能当然远不止这些,有兴趣的同学可以参考这里 http://docs.python.org/library/ctypes.html
使用Python 的扩展( Extending )机制
ctypes很方便地可以调用 C 的动态库,但是对 C++ 编译的动态库,调用起来很困难。这种情况利用 Python 的 Extending 机制就可以解决。 Python 提供了一套完整的框架来使用 C/C++ 编写扩展库,可以很灵活的开发 C++ 扩展模块。这种方法的缺点是工作量比较大,需要为每一个方法编写接口,这里不做详细介绍,可以参考: http://docs.python.org/extending/extending.html#writing-extensions-in-c
那么有什么办法可以高效的调用C++ 动态库呢,答案是 SWIG 。
使用SWIG 生成扩展模块
上面提到了Python 的扩展机制,缺点是工作量比较大,这里介绍一个工具 SWIG 。 SWIG 是一种简化脚本语言与 C/C++ 接口的开发工具,通过包装和编译 C 语言程序来达到与脚本语言通讯目的的工具。它正是基于 Python 的扩展机制,自动生成接口文件,再编译成可以被 Python 调用的动态库扩展模块。
使用SWIG 生成扩展模块分为以下几步:
将需要调用的代码编译成目标文件(.o) ;
用SWIG 读取编写描述文件 (.i) ,生成接口文件 (.cxx) ;
将接口文件编译为目标文件(.o) ;
将接口文件的目标文件和原代码段的目标文件一起编译成动态库 ;
假设有如下文件
swig_ex.cpp 需要转换成扩展库的原始代码,包含一个int fact(int) 函数
swig_ex.h 原始代码的头文件
swig_ex.i SWIG描述文件
swig_ex.i是一个描述文件,有 SWIG 自己的语法,比较简单,内容如下:
%mole swig_ex
%{
#define SWIG_FILE_WITH_INIT
#include "swig_ex.h"
%}
int fact(int n);
再写一个Makefile 来把这些文件编译成动态库 :
all: swig_ex.o swig_ex_wrap.o _swig_ex.so
swig_ex.o: swig_ex.cpp swig_ex.h #编译源文件
g++ -fPIC -c swig_ex.cpp
swig_ex_wrap.o: swig_ex.i swig_ex.o #根据 SWIG 描述文件 (.i) 生成接口文件 (.cxx) ,再编译之
swig -c++ -python swig_ex.i
g++ -O2 -fPIC -c swig_ex_wrap.cxx -I/home/work/linyi/autoframe/tool/python/include/python2.6/
_swig_ex.so: swig_ex_wrap.o #将目标文件打包成动态库
g++ -shared swig_ex.o swig_ex_wrap.o -o _swig_ex.so
.PHONY: clean
clean:
rm -rf swig_ex_wrap.* swig_ex.py _swig_ex.so
编译好以后会有一个so 和 py 文件,写一个 setup.py 把他们安装到 python 目录就可以和其他模块一样被 python 调用了:
Import swig_ex
swig_ex.fact(10)
参考文档地址:http://www.swig.org/Doc1.3/SWIGDocumentation.html
原始但有效的方法
除了上面这些方法,在Python 中借用 C/C++ 代码最原始有效的方法就是将代码编译成可执行程序,从 Python 里用 Popen 方法来调用获取输出。这种方法简单有效,缺点是不够灵活,有比较大的局限性,不过在很多情况下也已经足够了。
pipe = os.popen('./tool –a %s –b %s' % (“hello”, “world”))
re = pipe.read()
其他方法
以上这些方法基本上已经能满足Python 调用 C/C++ 的需求了,此外还有一些方法,例如使用 Boost.Python ,使用 Pyrex ,这些方法都能提供 Python 与 C/C++ 的交互。
总结
在Python 中引用 C/C++ 模块的方法较多,根据需要从中选择恰当的方法可以减少很多工作量。
在Python 中引用 C/C++ 模块弥补了 Python 脚本测试框架的很多不足,在提高代码复用率的同时,模块的性能也大大提高。
3. python怎么使用cython
1. Cython是什么?
它是一个用来快速生成Python扩展模块(extention mole)的工具
语法是Python和c的混血
Cython作为一个Python的编译器,在科学计算方面很流行,用于提高Python的速度,通过OpenMPI库还可以进行吧并行计算。
2. Cython安装(Windows)
我的环境是win7 x64, python27, vs2010
安装的基础是有一个c编译器(这里以vs2010为例)
从http://cython.org下载安装包,解压到一目录,进入该目录,在cmd命令行中执行
python setup.py install
注:执行过程可能遇到问题:Windows下pip安装包报错:Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat
解决方案:下载Microsoft Visual C++ Compiler for Python 2.7,点击直接安装即可。
3. 例子
例3.1:入门
创建hello.pyx,内容如下
def say_hello():
print "Hello World!"
创建setup.py,内容如下
from distutils.core import setup
from Cython.Build import cythonize
setup(name = 'Hello world app',
ext_moles = cythonize("hello.pyx"))
编译Cython代码
step1: 把.pyx文件被Cython便以为.c文件
step2: 把.c文件编译为可导入的使用模块.so(Windows下为.pyd)文件
1
2
python setup.py build
python setup.py install
注:可能出现问题:Unable to find vcvarsall.bat
原因:Python 2.7 会搜索 Visual Studio 2008.如果你电脑上没有这个版本的话就会报错。
如果装的是vs2010,那么在cmd命令行中执行
1
SET VS90COMNTOOLS=%VS100COMNTOOLS%
如果装的是vs2010,那么在cmd命令行中执行
1
SET VS90COMNTOOLS=%VS110COMNTOOLS%
执行
1
2
3
>>> import hello
>>> hello.say_hello()
Hello World!例3.2 通过静态类型提高速度
在Cython中可以通过标记静态类型来提高速度,凡是标记为静态类型的部分都会将动态语言类型变为简单的c代码,从而提速。
但是如果滥用静态类型,会降低可读性,甚至因类型设置不当导致错误类型检查造成速度降低。
例3.2.1 静态类型变量
Python原生态代码
compute.pyx
def f(x):
return x ** 2 - x
def integrate_f(a, b, N):
s = 0
dx = (b - a) / N
for i in range(N):
x += f(a + i * dx)
return s * dx
setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(
name = 'Hello world app',
ext_moles = cythonize("compute.pyx"),
)
test.py
import compute
import time
starttime = time.clock()
compute.integrate_f(3.2, 6.9, 1000000)
endtime = time.clock()
print "read: %f s" %(endtime - starttime)
执行
1
2
3
python setup.py build
python setup.py install
python test.py
结果
1
read: 0.332332 s
使用静态变量替换后的代码
compute2.pyx
def f(double x):
return x ** 2 - x
def integrate_f(double a, double b, int N):
cdef int i
cdef double s, dx
s = 0
dx = (b - a) / N
for i in range(N):
s += f(a + i * dx)
return s * d
setup2.py
from distutils.core import setup
from Cython.Build import cythonize
setup(
name = 'Hello world app',
ext_moles = cythonize("compute2.pyx"),
)
test2.py
import compute2
import time
starttime = time.clock()
compute2.integrate_f(3.2, 6.9, 1000000)
endtime = time.clock()
print "read: %f s" %(endtime - starttime)
执行
1
2
3
python setup.py build
python setup.py install
python test.py
结果
1
read: 0.109200s
结论
该测试用例,使用静态类型速度是不使用静态类型的3倍。
例3.2.2 静态类型函数
把compute2.pyx中的函数变为
cdef double f(double x):
return x ** 2 - x
def integrate_f(double a, double b, int N):
cdef int i
cdef double s, dx
s = 0
dx = (b - a) / N
for i in range(N):
s += f(a + i * dx)
return s * dx
结果
1
read: 0.084859 s
结论:比例子3.2.1速度又快了
例3.3 调用C函数
cdef extern from "math.h":
double sin(double)
double cos(double)
cpdef double Sin(double x):
return sin(x)
cpdef double Cos(double x):
return cos(x)
cpdef: 对于Python可使用的函数使用(为了使得在以后的Python程序中调用Sin,Cos函数,用cpdef,而不用cdef)
cdef: 对于C可使用的函数使用
请注意,上面的代码声明了 math.h 里的函数,提供给 Cython 使用。C编译器在编译时将会看到 math.h 的声明,但 Cython 不会去分析 math.h 和单独的定义。
4. python怎么使用cython
1.找个工具将这个接口API,自动转换成python版本的就可以了。好象是SWIG和Boost。 这两个以前看过,偶尔还试过几次。
2.之所以建议你用自动工具,就是因为python对于C++扩展麻烦些,对于C语言接口可以使用ctypes和cython简单解决。
5. 为什么python cython
与TNonblockingServer模式相比,THsHaServer在完成数据读取之后,将业务处理过程交由一个线程池来完成,主线程直接返回进行下一次循环操作,效率大大提升!
6. cython和python的区别
cython是用c写的python实现
Cython是不同的语言,相当于Python再加上些C特性,比如说类型声明。
7. cython与python的不同有哪些
Cython是Python的一个超集,结合了Python的易用性和原生代码的速度,可以编译成C语言,产生的性能提升可以从几个百分点到几个数量级,具体取决于手头的任务。
使用Cython,你可以避开Python的许多原生限制,或者完全超越Python,而无需放弃Python的简便性和便捷性。
Python代码可以直接调用C模块。这些C模块可以是通用的C库或专门为Python工作的库。Cython生成第二种类型的模块:与Python内部对话的C库,可以与现有的Python代码绑定在一起。
Cython代码在设计上看起来很像Python代码。如果你给Cython编译器提供了一个Python程序,它将会按原样接受它,但是Cython的原生加速器都不会起作用。但是如果你用Cython的特殊语法来修饰Python代码,那么Cython就可以用快速的C代替慢的Python对象。
请注意,Cython的方法是渐进的。这意味着开发人员可以从现有的Python应用程序开始,通过对代码立刻进行更改来加快速度,而不是从头开始重写整个应用程序。
这种方法通常与软件性能问题的性质相吻合。在大多数程序中,绝大多数CPU密集型代码都集中在一些热点上,也就是帕累托原则的一个版本,也被称为“80/20”规则。因此,Python应用程序中的大部分代码不需要进行性能优化,只需要几个关键部分。你可以逐渐将这些热点转换为Cython,从而获得你最需要的性能提升。程序的其余部分可以保留在Python中,以方便开发人员。
相关推荐:《Python入门教程》
Cython优势
除了能够加速已经编写的代码之外,Cython还具有其他几个优点:
使用外部C库可以更快
像NumPy这样的Python软件包可以在Python界面中打包C库,使它们易于使用。但是,这些包在Python和C之间来回切换会减慢速度。Cython可以让你直接与底层库进行通信,而不需要Python(也支持C ++库)。
可以同时使用C和Python内存管理
如果你使用Python对象,它们就像在普通的Python中一样被内存管理和垃圾收集。但是如果你想创建和管理自己的C级结构,并使用malloc/free来处理它们,你可以这样做,只记得自己清理一下。
可以根据需要选择安全性或速度
Cython通过decorator 和编译器指令(例如@boundscheck(False))自动执行对C中弹出的常见问题的运行时检查,例如对数组的超出边界访问。因此,由Cython生成的C代码默认比手动C代码安全得多。
如果确信在运行时不需要这些检查,则可以在整个模块上或仅在选择功能上禁用它们以获得额外的编译速度。
Cython还允许本地访问使用“缓冲协议”的Python结构,以直接访问存储在内存中的数据(无需中间复制)。Cython的“记忆视图”可以高速地在这些结构上进行工作,并且具有适合任务的安全级别。
Cython C代码可以从释放GIL中受益
Python的全局解释器锁(Global Interpreter Lock,GIL)同步解释器中的线程,保护对Python对象的访问并管理资源的争用。但GIL被广泛批评为Python性能的绊脚石,特别是在多核系统上。
如果有一段代码不会引用Python对象并执行长时间运行,那么可以使用nogil:指令将其标记为允许它在没有GIL的情况下运行。这使得Python中间人可以做其他事情,并允许Cython代码使用多个内核(附加工作)。
Cython可以使用Python类型的提示语法
Python有一个类型提示语法,主要由linters和代码检查器使用,而不是CPython解释器。 Cython有它自己的代码装饰的自定义语法,但是最近修改了Cython,你可以使用Python类型提示语法为Cython提供类型提示。
Cython限制
请记住,Cython不是一个魔术棒。它不会自动将每一个poky Python代码变成极速的C代码。为了充分利用Cython,你必须明智地使用它,并理解它的局限性:
常规Python代码的加速很少
当Cython遇到Python代码时,它不能完全翻译成C语言,它将这些代码转换成一系列对Python内部的C调用。这相当于将Python的解释器从执行循环中提取出来,这使得代码默认加速了15%到20%。请注意,这是最好的情况。在某些情况下,可能看不到性能改善,甚至性能下降。
原生Python数据结构有一点加速
Python提供了大量的数据结构 - 字符串,列表,元组,字典等等。它们对于开发者来说非常方便,而且他们自带了自动内存管理功能,但是他们比纯C慢。
Cython让你继续使用所有的Python数据结构,尽管没有太多的加速。这又是因为Cython只是在Python运行时调用创建和操作这些对象的C API。因此,Python数据结构的行为与Cython优化的Python代码大致相同:有时会得到一个提升,但只有一点。
Cython代码运行速度最快时,“纯C”
如果你在C中有一个标有cdef关键字的函数,那么它的所有变量和内联函数调用都是纯C的,所以它的运行速度可以和C一样快。 但是,如果该函数引用任何Python原生代码(如Python数据结构或对内部Python API的调用),则该调用将成为性能瓶颈。
幸运的是,Cython提供了一种方法来发现这些瓶颈:一个源代码报告,一目了然地显示您的Cython应用程序的哪些部分是纯C以及哪些部分与Python交互。 对应用程序进行了更好的优化,就会减少与Python的交互。
为Cython应用程序生成的源代码报告。 白色区域纯C;黄色区域显示与Python内部的交互。一个精心优化的Cython程序将尽可能的黄色。 展开的最后一行显示了解释其相应Cython代码的C代码。
Cython NumPy
Cython改进了基于C的第三方数字运算库(如NumPy)的使用。由于Cython代码编译为C,它可以直接与这些库进行交互,并将Python的瓶颈带出循环。
但是NumPy特别适用于Cython。 Cython对NumPy中的特定结构具有本地支持,并提供对NumPy数组的快速访问。在传统的Python脚本中使用的熟悉的NumPy语法可以在Cython中使用。
但是,如果要创建Cython和NumPy之间最接近的绑定,则需要使用Cython的自定义语法进一步修饰代码。例如,cimport语句允许Cython代码在编译时在库中查看C级构造,以实现最快的绑定。
由于NumPy被广泛使用,Cython支持NumPy“开箱即用”。如果你安装了NumPy,你可以在你的代码中声明cimport numpy,然后添加进一步的装饰来使用暴露的函数。
Cython分析和性能
可以通过分析代码并亲眼目睹瓶颈在哪里获得最佳性能。Cython为Python的cProfile模块提供钩子,因此可以使用Python自己的分析工具来查看Cython代码的执行情况。无需在工具组之间切换;可以继续所熟悉和喜爱的Python世界中工作。
它有助于记住所有情况下,Cython不是魔术,仍然适用明智的现实世界的表现实践。在Python和Cython之间来回穿梭越少,你的应用运行得越快。
例如,如果你有一个你想要在Cython中处理的对象的集合,那么不要在Python中迭代它,并且在每一步调用一个Cython函数。将整个集合传递给你的Cython模块并在那里迭代。这种技术经常在管理数据的库中使用,因此这是在自己的代码中模拟的好模型。
我们使用Python是因为它为程序员提供了便利,并且能够快速开发。有时程序员的工作效率是以牺牲性能为代价的。使用Cython,只需要一点点额外的努力就可以给你两全其美的好处。
8. cython和python可以混合写吗
1)Py3.X去除了long类型,现在只有一种整型——int,但它的行为就像2.X版本的long
2)新增了bytes类型,对应于2.X版本的八位串,定义一个bytes字面量的方法如下:
>>> b = b'china'
>>> type(b)
<type 'bytes'>
str对象和bytes对象可以使用.encode() (str -> bytes) or .decode() (bytes -> str)方法相互转化。
>>> s = b.decode()
>>> s
'china'
>>> b1 = s.encode()
>>> b1
b'china'
9. 如何使用cython编译扩展
先是安装Cython。由于我只有Windows,所以就只介绍这个平台。
英文的说明可以看《InstallingOnWindows》,共有2步:
一、安装MinGW。现在SF已不提供完整安装版了,只能下载在线安装版。由于Cython也支持C++,所以我也勾选了g++编译器。
装好后把MinGW目录/bin加入PATH环境变量,并保证gcc --version可以正确执行。
接着去Python目录\Lib\distutils下添加一个distutils.cfg文件,内容如下:
[build]
compiler = mingw32
实际上这最后一步也可不做,但每次编译都需要加一个-c参数来指定编译器。
二、安装Cython。
我是直接下载exe版本的,直接运行即可。Python 2.4可能还要做些额外处理,我没有这个版本,没法测试。
接着就可以来测试了,先来写个hello world。
hw.py:
def hi():
print "Hello World"
setup.py:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
cmdclass = {'build_ext': build_ext},
ext_moles = [Extension("hw", ["hw.py"])]
)
然后运行这段代码进行编译:
setup.py build_ext --inplace
这就生成了很多文件,其中hw.pyd就是生成的C扩展了。
接着测试一下:
>>> from hw import hi
>>> hi()
Hello World
然后来测试下性能:
csigma.py和pysigma.py:
def sigma(n):
a = 0
for i in xrange(n):
a += i
return a
测试脚本:
from timeit import Timer
print Timer('sigma(10000)','from csigma import sigma').timeit(10000)
print Timer('sigma(10000)','from pysigma import sigma').timeit(10000)
10. cython编译为可执行文件,目标机器上不用安装Python环境就可以执行
本来就是脚本语言,要做窗口程序的话用C#,VB,再不用易语言也可以
python,lua之类的这方面都有各种弊端
再看看别人怎么说的。