这是我的第一篇翻译,希望大家多多给出意见和建议。
如有转载,请注明出处。
原文来自:https://stackoverflow.com/questions/28362009/definition-of-def-cdef-and-cpdef-in-cython

问题

我想知道在我声明一个函数时def, cdef, cpdef的区别。
def 与其他两种的区别还算大致清晰。可是有时我见到声明时添加了返回值,有时见到的声明却没有添加返回值。

我还想知道在cython中如何声明一个字符串变量,因为我不知道怎么搞,我就按照声明对象的方式做了。

回答0

def 用来在Python中声明一个函数。因为Cython是基于C runtime的,所以允许我们使用cpdef
cdef 在C语言层面声明了函数。正如我们所知道的在C语言中你必须为每一个函数定义返回值的类型。有事函数返回值为 void,这就等于Python中的 return
Python是一个面向对象的语言。所以我们还可以在C++层面定义类方法,并在子类中重新。

举个栗子~

cdef class A:
cdef foo(self):
print "A" cdef class B(A)
cdef foo(self, x=None)
print "B", x cdef class C(B):
cpdef foo(self, x=True, int k=3)
print "C", x, k

总结一下,为什么我们要使用def, cdef, cpdef呢?因为我们使用Cython,你的Python代码在编译之前,会被转换为C代码。鉴于此,我们可以控制会变成C代码的那些项目。

更多拓展的信息我还是建议你去看官方的文档。
http://docs.cython.org/src/reference/language_basics.html

回答1

最关键的不同在于 where the function can be called from,def 函数可以被Python和Cython调用,cdef 函数可以被Cython和C调用。
这两种类型的函数都是既可以被带类型的变量也可以被不带类型的变量被声明,并且都会被Cython编译为C。

# A Cython class for illustrative purposes
cdef class C:
pass def f(int arg1, C arg2, arg3):
# takes an integer, a "C" and an untyped generic python object
pass cdef g(int arg1, C arg2, arg3):
pass

上面的栗子中,f 对Python可见(一旦它被imported Cython module中。而 g 不可能被call from Python,它将被翻译成C signature:

PyObject* some_name(int, struct __pyx_obj_11name_of_module_C *, PyObject*)

其中的 struct __pyx_obj_11name_of_module_C * 是我们的 class C 翻译成的 C struct。这就允许我们把它传递给 C 函数,比如作为一个函数指针。
相对而言,f 就不能轻易的被C调用了。

cdef 函数的限制

cdef 函数不能在我们的函数内定义。这是因为没有方法可以存储获取变量在C函数指针,如下代码就是不允许的。

# WON'T WORK!
def g(a):
cdef (int b):
return a+b

cdef 函数不能处理 *args *kwargs 类型的变量。这主要是因为它们不能轻易的翻译成 C signature。

cdef 函数的优势

cdef 函数可以接受任何类型的变量,包括哪些Python中没有的类型,比如指针。
def 函数总是返回一个Python对象,所以不能是一个具体返回值类型。

cdef int h(int* a):
# specify a return type and take a non-Python compatible argument
return a[0]

cdef 函数比 def 函数调用更快,因为它们会被翻译成一个更加简单的 C 函数调用。

cpdef 函数

cpdef 函数让Cython产生一个 cdef 函数(使得从Cython进行快速的函数调用)和一个 def 函数(使得我们可以从Pyhton调用)。就允许的变量类型而言,cpdef 函数具有 cdefdef 函数的限制。

什么时候使用 cdefcpdef 函数?

一旦函数被调用,那么 cdef 和 def 函数内部代码的运行速度没有区别。
因此我们仅在以下条件下使用 cdef 函数:

  1. 需要传递非Python类型
  2. 需要传递它作为一个函数指针到C
  3. 需要经常调用(加速函数调用很重要)而且不需要从Python调用

使用 cpdef 函数的条件:

  1. 需要经常调用(所以使用加速函数调用很重要)而且需要从Python调用

Cython中def,cdef,cpdef的区别的更多相关文章

  1. 【转】python类中super()和__init__()的区别

    [转]python类中super()和__init__()的区别 单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(se ...

  2. Python中生成器和迭代器的区别(代码在Python3.5下测试):

    https://blog.csdn.net/u014745194/article/details/70176117 Python中生成器和迭代器的区别(代码在Python3.5下测试):Num01–& ...

  3. 基于python中staticmethod和classmethod的区别(详解)

    例子 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 class A(object):   def foo(self,x):     print "executing foo ...

  4. Python中send()和sendall()的区别

    Python中send()和sendall()的区别 估计每个学习Python网络编程的人,都会遇到过这样的问题: send()和sendall()到底有什么区别? send()和sendall()原 ...

  5. python中_new_()与_init_()的区别

    __new__方法的使用 只有继承于object的新式类才能有__new__方法,__new__方法在创建类实例对象时由Python解释器自动调用,一般不用自己定义,Python默认调用该类的直接父类 ...

  6. 【转】为什么我们都理解错了HTTP中GET与POST的区别

    GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数. 你可能自己 ...

  7. Visual Studio 中 Build 和 Rebuild 的区别

    因为之前写的程序比较小,编译起来比较快,所以一直都没有太在意 Build 和 Rebuild 之间的区别,后来发现两个还是有很大不同. Build 只针对在上次编译之后更改过的文件进行编译,在项目比较 ...

  8. SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别

    SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是 EXEC 和 SP_EXECUTESQL ,我们先来看一下两种方 ...

  9. java集合中List与set的区别

       java集合中List与set的区别.     List可以存储元素为有序性并且元素可以相同.     set存储元素为无序性并且元素不可以相同.     下面贴几段代码感受一下: ArrayL ...

随机推荐

  1. Android Proguard.flags LOCAL_PROGUARD_FLAGS

    在Android项目中用到JNI,当用了proguard后,发现native方法找不到很多变量,原来是被produard优化掉了.所以,在JNI应用中该慎用progurad啊. 解决办法: 1.在An ...

  2. PHP 数字转汉字函数

    /** * 数字转汉字描述 */ function numToStr($num) { // 判断正确数字 if (!preg_match('/^(\d*)(\.\d+)?$/', $num)) ret ...

  3. SVN学习——简单入门之创建仓库、导入、检出(一)

    从刚刚参加工作就开始使用svn,清晰的记得那年师姐比较生气的来找我:“你怎么又不更新就提交代码了,把我写的都给覆盖掉了”,哈哈~ 虽然一直在用svn,不过在日常工作中主要用到的是简单的操作,而且大多数 ...

  4. C#使用Process类杀死进程,执行命令等

    c#之process类相关整理 一.根据进程名获取进程的用户名? 需要添加对 System.Management.dll 的引用 using System.Diagnostics; using Sys ...

  5. Selenium2学习(十一)-- select下拉框

    本篇以百度设置下拉选项框为案例,详细介绍select下拉框相关的操作方法. 一.认识select    1.打开百度-设置-搜索设置界面,如下图所示 2.箭头所指位置,就是select选项框,打开页面 ...

  6. how to create folders in batches

    you need be good at thinking when you see problem. Work experience:when you need to copy web chinese ...

  7. pip pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool

    设置超时时间: pip --default-timeout=100 install  Pillow

  8. 【洛谷5279】[ZJOI2019] 麻将(“胡牌自动机”上DP)

    点此看题面 大致题意: 给你13张麻将牌,问你期望再摸多少张牌可以满足存在一个胡的子集. 似乎ZJOI2019Day1的最大收获是知道了什么是胡牌? 一个显然的性质 首先我们要知道一个显然的性质,即对 ...

  9. 【[SDOI2014]旅行】

    听说这是动态开点主席树的板子题,但是发现我还不会,于是就来写一写 其实跟主席树一个样子的 这里就是存个板子吧 #include<cstdio> #include<cstring> ...

  10. 使用maven创建项目

    http://192.168.4.112/rdmanager/main/index.jhtml 1.对于第一次下载某个项目的源码,按照下面的步骤进行: (1)在D:\projects\目录下的空白位置 ...