Cython官方文档中文翻译:初级教程

佐手、 提交于 2019-12-21 20:25:14
  • 说明

    尝试翻译Cython Documentation以助学习。

    水平有限,乐迎指正;文档首页:《Cython官方文档中文翻译

  • Cython基础

    Cython的根本特性可以总结如下:Cython是带有C数据类型的Python

    Cython就是PythonPython的几乎所有代码都是有效的Cython代码。(虽然也有一些局限( Limitations),但就目前而言还是非常接近的)Cython编译器将代码转为C代码,从而实现对Python/C API的平等调用。

    因为变量和参数可声明为C数据类型,故Cython能量远不止此。控制Python值C值的代码可以自由融合,当需要时则自动转换。Python的引用计数维护和错误检查以及全部错误处理功能也都是自动的,其中就包括try-excepttry-finally语句(即便是在处理C数据的过程中)

  • Cython实现Hello World

    鉴于Cython可以识别任意有效的python源文件,开始时的困难之一就是搞懂如何编译你的扩展。

    让我们从标准的python hello world开始:

    print("Hello World")
    

    将上述代码保存在一个helloworld.pyx文件内,然后创建setup.py文件,这是一个Makefile(更详细了解参见 Source Files and Compilation),setup.py文件内容如下:

    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup(ext_modules=cythonize("helloworld.pyx"))
    

    上述准备好两个素材文件,使用下述命令行命令创建Cython文件

    $ python setup.py build_ext --inplace
    

    上述命令会在本地文件夹内创建一个helloworld.sounix系统)或helloworld.pyxwindows系统)文件。现在来使用这个文件,打开一个Python 解释器(在命令行中cmd > python),之后类似引入常规模块一样import这个文件:

    >>> import helloworld
    Hello world
    

    恭喜你!你现在就知道如何构建一个Cython扩展了。但是,这个例子并没有体现出使用Cython的必要性,下面让我们来看一个更实用的例子。

    译者注:详细实现过程及可能出现问题,参见《Cython使用案例之:输出Hello World》

  • pyximport:面向开发人员的Cython编译

    如果你的模块无需其他C库或特殊的构建设置build setup),那么你可以采用pyximport模块,最初由Paul Prescod开发,用import直接导入*.pyx文件,这样就避免每次更新代码后都单独重新执行运行setup.py的动作。与Cython*绑定安装,实用方法如下:

    >>> import pyximport; pyximport.install()
    >>> import helloworld
    
    

    译者注:上述代码在cmd > python解释器中运行,会直接实现编译过程并导入,文件夹中并不生成.pyx.c文件。

    在这里插入图片描述

    Pyximport模块还对普通Python模块提供了实验性编程支持,这允许你在每一个Python导入(import)的*.pyx.py模块上运行Cython,包括标准库和后续安装的包。当然,还有很多模块是Cython编译不了的,在这种情况下,import机制将返回去加载Python源模块。.py*的导入机制如下:

    >>> pyximport.install(pyimport=True)
    

    不建议在最终用户端实用*Pyximport构建代码,因为其与import*系统挂钩。适合最终用户端的方式是提供以轮包(wheel packaging format)形式存在的预构建(pre-built)的二进制包。

  • 斐波那契(Fibonacci)的乐趣

    Python官方教程有定义一个简单的fibonacci函数:

    from __future__ import print_function
    def fib(n):
        """
        Print the Fibonacci series up to n
        """
        a, b = 0, 1
        while b < n:
            print(b ,end= '')
            a, b = b, a + b
        print()
    

    按照Hello World例子的步骤,先创建一个*.pyx扩展,比如fib.pyx*,然后创建一个setup.py,直接实用Hello World例中的setup.py,只需要更改Cython文件的名字和生成模块的名字,如下:

    from distutils.core import setup
    from Cython.Build import cythonize
    setup(ext_modules = cythonize("fib.pyx"))
    

    创建扩展的命令与用于helloworld.pyx的命令是一样的:

    $ python setup.py build_ext --inplace   # 文件所在路径下,命令行中运行
    

    使用新的扩展:

    >>> import fib
    >>> fib.fib(2000)
    1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
    

    译者注:

    同样,可以采用pyximport来实现上述编译过程:

    # 第一步:命令行进入python
    $ py # 本机需要用py表示python3
    # 第二步:在python中采用pyximport编译
    >>> import pyximport;pyximport.install()
    >>> fib
    # 第三步:在python内调用fib模块的fib函数
    >>> fib.fib(2000)
    1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
    

    在这里插入图片描述

  • 质数

    这里是个小例子,展示Cython功能。也是一个常规功能:找质数(素数)的个数

    你告诉他你需要多少个质数,它给你返回一个包含所需质数的list

    prime.pyx文件

    def primes(int nb_primes):
    	cdef int n, i, len_p
    	cdef int p[1000]
    	if nb_primes > 1000:
    		nb_primes = 1000
    	len_p = 0 # p中当前元素数量
    	n = 2
    	while len_p < nb_primes:
    		# 判断n是否质数
    		for i in p[:len_p]:
    			if n % i == 0:
    				break
    			# 如果上述循环未中断程序,那我们就得到了一个质数
    			else:
    				p[len_p] = n
    				len_p += 1
    			n += 1
    	# 以Python list形式返回结果
    	result_as_list = [prime for prime in p[:len_p]]
    	return result_as_list
    
  • References

  1. 原文链接
  2. Cython使用案例之:输出Hello World
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!