python作为一门脚本语言,其好处是语法简单,很多东西都已经封装好了,直接拿过来用就行,所以实现同样一个功能,用Python写要比用C/C++代码量会少得多。但是优点也必然也伴随着缺点(这是肯定的,不然还要其他语言干嘛),python最被人诟病的一个地方可能就是其运行速度了。这这是大部分脚本语言共同面对的问题,因为没有编译过程,直接逐行执行,所以要慢了一大截。所以在一些对速度要求很高的场合,一般都是使用C/C++这种编译型语言来写。但是很多时候,我们既想使用python的简介优美,又不想损失太多的性能,这个时候有没有办法将python与C/C++结合到一起呢?这样在性能与速度要求不高的地方,可以用pyhton写,而关键的运算部分用C/C++写,这样就太好了。python在做科学计算或者数据分析时,这是一个非常普遍的需求。要想实现这个功能,python为我们提供了不止一种解决办法。下面我就逐一给大家介绍。

一、Cython 混合python与C

官方网址:http://docs.cython.org/en/latest/src/quickstart/overview.html。首先来看看cython的官方介绍吧。

[Cython] is a programming language that makes writing C extensions for the Python language as easy as Python itself. It aims to become a superset of the [Python]language which gives it high-level, object-oriented, functional, and dynamic programming. Its main feature on top of these is support for optional static type declarations as part of the language. The source code gets translated into optimized C/C++ code and compiled as Python extension modules. This allows for both very fast program execution and tight integration with external C libraries, while keeping up the high programmer productivity for which the Python language is well known.

简单来说,cython就是一个内置了c数据类型的python,它是一个python的超集,兼容几乎所有的纯python代码,但是又可以使用c的数据类型。这样就可以同时使用c库,又不失python的优雅。

好了,不讲太多废话,直接来看cython如何使用吧。这里的介绍大部分来自官网,由于cython涉及到的东西还比较多,所以这里只是简单的入门介绍,详细的信息请移步英文官网。

使用cython有两种方式:第一个是编译生成Python扩展文件(有点类似于dll,即动态链接库),可以直接import使用。第二个是使用jupyter notebook或sage notebook 内联 cython代码。

先看第一种。还是举最经典的hello world的例子吧。新建一个hello.pyx文件,定义一个hello函数如下:

def hello(name):

print("Hello %s." % name)

然后,我们来写一个setup.py 文件(写python扩展几乎都要写setup.py文件,我之前也简单介绍过怎么写)如下:

1 #!/usr/bin/env python

2 # -*- coding: utf-8 -*-

3 # @Time : 2017/5/8 9:09

4 # @Author : Lyrichu

5 # @Email : 919987476@qq.com

6 # @File : setup.py

7 '''

8 @Description: setup.py for hello.pyx

9 '''

10 from Cython.Build import cythonize

11 from distutils.core import setup

12

13 # 编写setup函数

14 setup(

15 name = "Hello",

16 ext_modules = cythonize("hello.pyx")

17 )

其中 ext_modules 里面写你要 编译的.pyx文件名字。OK,所有工作都完成了。接下来,进入cmd,切换到setup.py 所在的文件,然后执行命令: python setup.py build_ext --inplace 就会编译生成一个build 文件夹以及一个.pyd文件了,这个pyd文件就是python的动态扩展库,--inplace 的意思是在当前文件目录下生成.pyd文件,不加这一句就会在build文件夹中生成。截图如下:

图 1

可以看出,除了生成了一个pyd文件之外,还生成了一个.c文件。test.py是我们用来测试的文件,在里面写如下内容:

from hello import hello

hello("lyric")

从hello 模块导入 hello函数,然后直接调用就可以了。结果输出 Hello lyric.

再来看如何 在 jupyter notebook中使用cython。如果你装过ipython,一个升级版的python交互式环境,你应该听过 ipyhton notebook的大名,现在它升级了,改名叫jupyter notebook 了。简单来说,这个就是一个可以在网页环境下交互式使用python的工具,不仅可以实时看到计算结果,还可以直接展示表格,图片等,功能还是非常强大的。首先你得安装jupyter notebook.我印象中安装了ipython之后应该就会带了jupyter了。如果没有,可以直接 pip install jupyter .然后输入命令 jupyter notebook 就会在浏览器中打开jupyter了。如下图2 所示:

图 2

点击右上角的new按钮,可以选择新建一个文本文件或者文件夹,markdown或者python文件,这里我们选择新建一个pyhton 文件,然后就会转到一个新的窗口了,如下图3:

图 3

In[]:和ipython一样,就代表着我们要输入代码的地方,输入代码之后,点击向右的三角形符号,就会执行代码了。

首先输入 %load_ext cython ,然后执行,%开头的语句是jupyter的魔法命令,%是行命令,%%是单元命令,具体不多说,有空给大家专门介绍一下notebook的使用。

接下来输入:

1 %%cython

2 cdef int a = 0

3 for i in range(10):

4 a += i

5 print(a)

%%cython 表明将cython内嵌到jupyter,cdef 是cython的关键字,用于定义c类型,这里将a定义为c中的int类型,并且初始化为0.

然后后面的循环就是累加0到9的意思,最后输出45.

另外,我们如果想分析代码 的执行情况,可以输入 %%cython --annotate 命令,这样就可以输出结果的同时,也输出 详细的代码执行情况报告了。截图如图4 所示:

图 4

jupyter notebook 可以内嵌cython,不用我们手写setup.py 文件,省去了编译的过程,方便了cython的使用,所以不是正式做项目,只是写一写小东西用jupyter+cython还是非常方便的。

前面提到了 cdef,再举一个稍微复杂点的例子吧。还是引用官网的例子,写一个算积分的函数.新建 integrate.pyx 文件,写入如下内容:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# @Time : 2017/5/8 9:26

# @Author : Lyrichu

# @Email : 919987476@qq.com

# @File : integrate.py

'''

@Description: 积分运算,使用 cython cdef 关键字

'''

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)*dx

return s # 返回定积分

这段代码应该也是比较好理解的,f()函数是被积函数,a,b是积分的上下限,N是分割小矩形的个数,注意这里将 变量i,s,dx全部都用cdef 声明为c类型了,一般来说,在需要密集计算的地方比如循环或者复杂运算,可以将对应的变量声明为c类型,可以加快运行速度。

然后和上面一样编写 setup.py ,就是把 pyx的文件名改一下,代码我就不贴了。然后python setup.py build_ext --inplace 执行。得到pyd文件,编写测试文件test.py如下:

1 #!/usr/bin/env python

2 # -*- coding: utf-8 -*-

3 # @Time : 2017/5/8 9:35

4 # @Author : Lyrichu

5 # @Email : 919987476@qq.com

6 # @File : test.py

7 '''

8 @Description: 测试使用cython 混合c与python的integrate 函数与纯python写的integrate函数速度上的差异

9 '''

10 from integrate import integrate_f

11 import time

12

13 a = 1 # 积分区间下界

14 b = 2 # 积分区间上界

15 N = 10000 # 划分区间个数

16

17 # 使用纯python代码写的integrate函数

18 def py_f(x):

19 return x**2 - x

20

21 def py_integrate_f(a,b,N):

22 dx = (b-a)/N

23 s = 0

24 for i in range(N):

25 s += py_f(a + i*dx)*dx

26 return s

27

28 start_time1 = time.time()

29 integrate_f_res = integrate_f(a,b,N)

30 print("integrate_f_res = %s" % integrate_f_res)

31 end_time1 = time.time()

32 print(u"cython 版本计算耗时:%.8f" % (end_time1 - start_time1))

33

34 start_time2 = time.time()

35 py_integrate_f_res = py_integrate_f(a,b,N)

36 print("py_integrate_f_res = %s" % py_integrate_f_res)

37 end_time2 = time.time()

38 print(u"python 版本计算耗时:%.8f" % (end_time2 - start_time2))

上面的代码,我们重新使用python写了一个积分函数py_integrate_f,与pyd中的integrate_f 函数进行运算对比,结果如下(图5):

图5

可以看出,使用了cython的版本比纯Python的版本大概快了4、5倍的样子,而这仅仅是将几个变量改为c类型的结果,可见,cython确实可以方便地对python与c进行混合,获得速度上的提升,又不失去Python的简洁优美。

最后再来说下cython 如何调用c libraries. C 语言 stdlib 库有一个 atoi函数,可以将字符串转化为整数,math库有一个sin函数,我们就以这两个函数为例。新建 calling_c.pyx 文件,文件内容如下:

from libc.stdlib cimport atoi

from libc.math cimport sin

def parse_char_to_int(char * s):

assert s is not NULL,"byte string value is NULL"

return atoi(s)

def f_sin_squared(double x):

return sin(x*x)

前两行导入了C语言中的函数,然后我们自定义了两个函数,parse_char_to_int 可以将字符串转换为整数,f_sin_squared 计算 x平方的sin函数值。写 setup.py 文件,和之前差不多,但是要注意的是,在unix系统下,math库默认是不链接的,所以需要指明其位置,那么在unix系统下,setup.py 文件的内容就需要增加Extension 一项,如下:

from distutils.core import setup

from distutils.extension import Extension

from Cython.Build import cythonize

ext_modules=[

Extension("calling_c",

sources=["calling_c.pyx"],

libraries=["m"] # Unix-like specific

)

]

setup(

name = "Calling_c",

ext_modules = cythonize(ext_modules)

)

然后直接编即可。test.py文件如下:

1 #!/usr/bin/env python

2 # -*- coding: utf-8 -*-

3 # @Time : 2017/5/8 12:21

4 # @Author : Lyrichu

5 # @Email : 919987476@qq.com

6 # @File : test.py

7 '''

8 @Description: test file

9 '''

10 from calling_c import f_sin_squared,parse_char_to_int

11 str = "012"

12 str_b = bytes(str,encoding='utf-8')

13 n = parse_char_to_int(str_b)

14 print("n = %d" %n)

15 from math import pi,sqrt

16 x = sqrt(pi/2)

17 res = f_sin_squared(x)

18 print("sin(pi/2)=%f" % res)

需要注意的是,Python字符串不能直接传入 parse_char_to_int 函数,需要将其转换为 bytes 类型再传入。运行结果为:

n = 12

sin(pi/2)=1.000000

如果不想通过libc导入c语言模块,cython也允许我们自己声明c函数原型来导入,一个例子如下:

# 自己声明c函数原型

cdef extern from "math.h":

cpdef double cos(double x)

def f_cos(double x):

return cos(x)

使用了 extern 关键字。

每次都编写setup.py 文件,然后编译,略显麻烦。cython还提供了一种更简单的方法:pyximport。通过导入pyximport(安装cython时会自动安装),在没有引入额外的c库的情况下,可以直接调用pyx中的函数,更为直接与方便。以前面的hello 模块为例,编写好hello.py文件之后,编写一个pyximport_test.py 文件,文件内容如下:

import pyximport

pyximport.install()

import hello

hello.hello("lyric")

直接运行就会发现,确实可以正确导入hello模块。

cython的更多内容,请大家自行访问官网查看。

其他python与c/c++ 混合编程的方式主要还有 使用 ctypes,cffi模块以及swig。本来想一起写的,想想还是分开写吧,不然太长了。后续会陆续更新,敬请关注。

python c++情侣网名是什么意思_Python 与 C/C++ 交互的几种方式相关推荐

  1. python c++情侣网名是什么意思_Python PK C++,究竟谁更胜一筹?

    作者 | Farhad Malik 译者 | 弯月,编辑 | 屠敏来源 | CSDN(ID:CSDNnews) 在编程生涯的早期阶段,我参与过一款C++数学优化应用程序的开发,这个程序对性能的要求很高 ...

  2. python c++情侣网名是什么意思_Python, C++, Java都有面对对象编程,为什么只有Java的那么出名?...

    因为java的oop面向对象相对纯粹,当然也不绝对纯粹,比如java也还有原始数据类型,并不是真的万事万物都是对象,后续的一些语言,比如scala,kotlin,dart,swift都做到了更加纯粹的 ...

  3. python c++情侣网名是什么意思_“果然,他用的是情侣网名!”

    "果然,他用的是情侣网名!" 情侣网名:小敢敢不憨 / 小憨憨不敢 情侣网名:人间水蜜桃 / 人间粑粑柑 情侣网名:星星泡饭/地球炒饭 情侣网名:似朝朝/亦暮暮 情侣网名:醒捕时光 ...

  4. python c++情侣网名是什么意思_如何实现 C/C++ 与 Python 的通信?

    ########## 以下所有文字均为答主手敲,转载请注明出处和作者 ########## ## 更新:关于ctypes,见拙作 聊聊Python ctypes 模块 - 蛇之魅惑 - 知乎专栏 属于 ...

  5. python c++情侣网名是什么意思_网友:c++与Python,究竟谁才是大哥?

    一直以来,在 TIOBE 编程语言排行榜中,简单易用的新贵 Python 和老将 C++ 是强劲的竞争对手,不过 C++ 和 Python 都是非常流行的编程语言,对于开发者而言,在选择语言利器时究竟 ...

  6. python c++情侣网名是什么意思_c++中嵌入python 看什么意思

    展开全部 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 ...

  7. python c++情侣网名含义_python的对象与名字绑定(转贴,此文甚好)

    i = 1 这是一个再简单不过的赋值语句,即便是才开始学习编程的新手也能脱口而出它的含义 -- "设置变量i的值为1". i = 2 "将变量i的值改为2",当 ...

  8. python c++情侣网名是什么意思_c++和Python的选择?

    想不到知友这么敏感,评论中有人说这是软文,也是醉了... 以下均用某在线学习网站代替. ------------------ 先说下我的背景: 1.我刚上完某在线学习网站的自动驾驶Term1的课程,T ...

  9. python c++情侣网名含义_集Python、C++、R为一体的语言,她是?

    Julia 之所以这么受欢迎,这与它解决了工程师们一个"坑爹"问题有关:工程师们为了在数据分析中获得速度和易用性,不得不首先用一种语言编码,然后用另一种语言重写,即很多人口中的&q ...

最新文章

  1. iOS 获取Assets中的启动页
  2. 太阳能发电产业有望大发展
  3. 贴牌是赢在当下,创牌才会更有未来
  4. python工作区是什么_VSCode工作区
  5. 华为史上最大规模升级!鸿蒙系统进度发布:近百款机型已适配
  6. maven手动添加第三方的jar包
  7. h5 手风琴效果_小程序-实现折叠面板-手风琴效果
  8. c语言printf族函数,C语言中的printf族函数深入详解
  9. 在Word中使用Quick Parts功能
  10. 普歌-码上鸿鹄团队:在Nuxt(vue)渲染模板中使用mock.js随机生成数据
  11. 群晖docker安装青龙面板自动狗东京豆领取
  12. Java8 Stream接口流式方法:map操作、filter操作以及flatMap操作
  13. wps页眉添加下划线
  14. [RK3568 Android11] 开发之APP应用切换USB OTG模式
  15. 基本数据结构——线性结构(有序表)
  16. eclipse字体颜色设置的方法
  17. 华为计算机魔术,华为荣耀magic给大家变了一个魔术,想“拆穿”他吗?
  18. c语言 qsort 改进篇
  19. 联想 n700 android,联想双模触控无线鼠标N700 双模式解析
  20. 全媒体群管理平台软件,有哪些功能?

热门文章

  1. SaaS系统:做难有意思的事
  2. java 获取不到cookie_cookie获取不到的问题
  3. 产品经理,如何用底层逻辑去旅行?
  4. 谷歌云端硬盘直接下载方法
  5. JAVAEE框架技术之8-myBatis ORM框架技术参数和动态SQL语句
  6. 魔兽世界中的一些公式
  7. 【翻译】关于程序员的59条搞笑但却真实无比的编程语录
  8. Word2016自带墨迹公式转换成mathtype公式类型
  9. excel表格如何改变里面的文字方向?
  10. 中丹学院计算机,揭秘国科大北京综合评价测试:科学家当考官,没有“固定套路”...