第1篇:Cython的數(shù)據(jù)類型

前言:這遍文章,是翻譯自官方文檔,覺得原官方文檔的例子有些抽象,所以我用一些具體的示例代碼替換了。

Python作為一種動(dòng)態(tài)語言, 它鼓勵(lì)的編程風(fēng)格優(yōu)先考慮類和對(duì)象的方法和屬性方面,而不是它們?nèi)绾芜m合哪種類繼承結(jié)構(gòu)。

這可以使Python成為一種非常輕松和舒適的快速開發(fā)語言,但需要付出代價(jià) - 管理數(shù)據(jù)類型的繁重工作會(huì)被轉(zhuǎn)嫁到解釋器上。在運(yùn)行時(shí),解釋器需要搜索命名空間,獲取屬性以及解析參數(shù)和關(guān)鍵字元組方面會(huì)消耗大量的時(shí)間。這種運(yùn)行時(shí)“后期綁定”是Python相對(duì)緩慢的主要原因。而Cython就使用類似于C++"早期綁定的"技術(shù),并且保留了大部分C/C++的特性,在編譯靜態(tài)版本的擴(kuò)展庫后,速度基本上等同于C/C++的運(yùn)行速度.

C變量和類型定義

cdef語句用于聲明C變量,無論是本地變量還是模塊級(jí)變量:

cdef int age;
cdef float score;

//聲明一個(gè)結(jié)構(gòu)體
cdef struct Person:
  int age
  char* name
#end-cdef

注意Structs可以聲明為cdef packed struct,它與C指令具有相同的效果

結(jié)構(gòu)體的初始化

  • 使用struct的字面量進(jìn)行初始化
cdef Person p
p=Person(23,"Lisa")
  • 使用類似關(guān)鍵的參數(shù)方式進(jìn)行初始化
cdef Person p
p=Person(age=23,name="Lisa")
  • 使用Python的dict進(jìn)行賦值,這將使用Cython的自動(dòng)轉(zhuǎn)換功能對(duì)結(jié)構(gòu)體逐個(gè)成員賦值。 請(qǐng)注意,這涉及更多的Python開銷
cdef Person p
p={"age":23,"name":"Lisa"}

目前沒有用于定義常量的特殊語法,但您可以為此目的使用匿名枚舉聲明,例如:

cdef enum:
   OPEN=1
   CLOSE=0
#end-cdef

注意:struct,union和enum僅在定義類型時(shí)使用,而不是在引用它時(shí)使用。 例如,要聲明一個(gè)指向Person的指針變量,你會(huì)寫:

cdef struct Person: 
    char* name
    int age
#end-cdef
/**正確寫法**/
cdef Person *jk

/*錯(cuò)誤寫法*/
cdef struct Person *jk

cdef 還可以用于聲明屬于c / cython的函數(shù)

cdef  int add(int a,int b):
    return a+b
#end-cdef

Cython中有三種函數(shù)定義:

  • def:Python函數(shù)是使用def語句定義的,就像在Python中一樣。它們將Python對(duì)象作為參數(shù)并返回Python對(duì)象。
  • cdef:Cython函數(shù)使用新的cdef語句定義。它們將Python對(duì)象或C值作為參數(shù),并且可以返回Python對(duì)象或C值。
  • cpdef:Hybrid函數(shù)(別以為是某田的混動(dòng)技術(shù)-___,-),允許從任何地方調(diào)用cpdef聲明的混合函數(shù),但在從其他Cython代碼調(diào)用時(shí)Hybrid函數(shù)會(huì)獲得C一樣的速度。

即使從Cython調(diào)用,也可以通過子類或?qū)嵗龑傩陨系腜ython方法覆蓋cpdef聲明的方法或?qū)傩?/strong>。如果發(fā)生這種情況,就得不到性能的提升,即使它沒有被覆蓋,跟調(diào)用cdef方法相比,從Cython調(diào)用cpdef方法的開銷很小,可以忽略不計(jì)。

Cython函數(shù)中的參數(shù)

可以使用常規(guī)C聲明語法將任一類型的函數(shù)的參數(shù)聲明為具有C數(shù)據(jù)類型。 例如:

當(dāng)Python函數(shù)的參數(shù)聲明為具有C數(shù)據(jù)類型時(shí),它將作為Python對(duì)象傳入,并在可能的情況下自動(dòng)轉(zhuǎn)換為C值。 請(qǐng)看如下示例:

//python函數(shù)
def eat(int n,char* food):
    return f'今天我吃了{(lán)n}次{food}'
#end-def

/*等價(jià)于*/
def eat(n,food):
     cdef int i=n
     cdef char* food=food
     return f'今天我吃了{(lán)n}次{food}'
#end-def

目前,只能對(duì)數(shù)字類型,字符串類型和結(jié)構(gòu)體進(jìn)行自動(dòng)轉(zhuǎn)換(以遞歸方式組合任何這些類型); 嘗試將任何其他類型用于Python函數(shù)的參數(shù)將導(dǎo)致編譯時(shí)錯(cuò)誤。在處理字符串的時(shí)候,在調(diào)用一個(gè)引用后必須確保該指針是否正被用, 可以從Python映射中獲取結(jié)構(gòu),如果要在函數(shù)返回后,在處理字符串的時(shí)候,必須確保該指針是否正在使用。另一方面,Cython函數(shù)可以具有任何類型的參數(shù),因?yàn)樗鼈兪鞘褂闷胀ǖ腃函數(shù)調(diào)用直接傳遞的。

使用帶有Python對(duì)象返回類型的cdef聲明的函數(shù)(如Python函數(shù)),當(dāng)執(zhí)行離開函數(shù)體而沒有顯式返回值時(shí),將返回None值。這與C / C ++形成對(duì)比,后者使返回值未定義。 在非Python對(duì)象返回類型的情況下,返回等價(jià)于零的值,例如,0表示int,F(xiàn)alse表示bint,NULL表示指針類型。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 文章轉(zhuǎn)自:https://zhuanlan.zhihu.com/p/24311879 當(dāng)人們提到 Python 的...
    yalesaleng閱讀 37,371評(píng)論 3 10
  • 姓名:唐來賓 學(xué)號(hào):17101223417 轉(zhuǎn)載http://mp.weixin.qq.com/s/S6BN8P4...
    ahbz_t閱讀 1,353評(píng)論 0 1
  • Cython代碼和Python代碼區(qū)別 代碼運(yùn)行在IPython-Notebook中,在IPython-Noteb...
    Arthurcsh閱讀 1,217評(píng)論 0 2
  • 我 獨(dú)行于門前小路 , 耳邊環(huán)繞著音樂。 第一次,去往遠(yuǎn)方, 我不要看他們的眼睛, 我不會(huì)回頭, 我怕,我忍不住。...
    汐陽閱讀 166評(píng)論 0 0
  • 今天帶著一諾去上班,把這兩天落下的作業(yè)補(bǔ)上,我知道我不在家他就是“老大”,肯定不會(huì)學(xué)習(xí),爺爺奶奶管不了她??赡苡悬c(diǎn)...
    諾諾辰辰媽媽閱讀 159評(píng)論 0 3

友情鏈接更多精彩內(nèi)容