第7篇 Cython封裝C++代碼(中)

至此,我們已經(jīng)在pyx文件的命名空間中公開(kāi)了C ++ MoneyFormator類(lèi)型的接口。 現(xiàn)在,我們需要使它可以從外部Python代碼訪(fǎng)問(wèn)(這是我們的重點(diǎn))在前一篇文章我們通過(guò)面向過(guò)程的編程方式已經(jīng)實(shí)現(xiàn)了。


常見(jiàn)的編程實(shí)踐是創(chuàng)建一個(gè)Cython擴(kuò)展類(lèi)型,該類(lèi)型將封裝后的C ++類(lèi)實(shí)例作為屬性,并創(chuàng)建一堆Cython類(lèi)的方法,這些類(lèi)方法內(nèi)部調(diào)用C++類(lèi)實(shí)例的對(duì)應(yīng)的方法。 因此,將前一篇中currency.pxd中的Cython類(lèi)接口導(dǎo)入到一個(gè)全新的pyx文件中,這里命名為monfmt.pyx,我們重新創(chuàng)建一個(gè)擴(kuò)展模塊,該模塊內(nèi)部就是使用Cython擴(kuò)展類(lèi)來(lái)調(diào)用C++類(lèi)的接口,如下代碼所示。

#distutils:language=c++
#cython:language_level=3

from currency cimport MoneyFormator as _MoneyFormat
from libcpp.string cimport string

#https://stackoverflow.com/questions/13201886/cython-and-constructors-of-classes
cdef class MoneyFormator:

    cdef _MoneyFormat* fmt
    cdef public double digit
        
    def __cinit__(self,str locName="zh_CN.UTF-8",double n=0.0):
        if locName=='zh_CN.UTF-8':
            self.fmt=new _MoneyFormat()
        else:
            self.fmt=new _MoneyFormat(locName.encode('utf-8'))

        self.digit=n
    
    cpdef string format(self,double value):
        self.digit=value
        return self.fmt.str(value)
    
    def __repr__(self):
        if self.fmt!=NULL and self.digit>0:
            return self.fmt.str(self.digit).decode("utf-8")
        else:
            return self.fmt.str(0).decode('utf-8')
    
    def __dealloc__(self):
        if self.fmt!=NULL:
            del self.fmt
         

這個(gè)Cython類(lèi)語(yǔ)法上沒(méi)什么好說(shuō)的,我假設(shè)你已經(jīng)閱讀過(guò)前6篇Cython編程隨筆了,在Python代碼中調(diào)用如下圖所示。


ss8.png

Cython類(lèi)方法的重載問(wèn)題

唯一注意的是,上面的調(diào)用示例,我們剛開(kāi)始以默認(rèn)的參數(shù)實(shí)例化了MoneyFormator對(duì)象fmt,我們調(diào)用時(shí)沒(méi)有傳遞參數(shù),但實(shí)際上我們調(diào)用了一個(gè)帶參數(shù)的構(gòu)造函數(shù),而非默認(rèn)構(gòu)造,其原型是

MoneyFormator. __ cinit __(self,str,double)

其實(shí)這里我們要討論一個(gè)額外的問(wèn)題就是Cython擴(kuò)展類(lèi)方法的重載(Overloaded),注意而非重寫(xiě),讀者千萬(wàn)不能將C/C++/Java這類(lèi)面向?qū)ο笳Z(yǔ)言中的重載概念套在Cython擴(kuò)展類(lèi)中,因?yàn)镃ython重載的特性體現(xiàn)兩個(gè)方面。我們理解Cython重載問(wèn)題過(guò)程中,我們重溫一下重載的概念:

重載就是為具有兩個(gè)或以上具有相同名稱(chēng)但參數(shù)不同的函數(shù)的過(guò)程,在C/C++中稱(chēng)為函數(shù)重載。 在函數(shù)重載中,通過(guò)使用不同類(lèi)型參數(shù)不同數(shù)量參數(shù)來(lái)重新定義函數(shù)。 只有通過(guò)這些差異,編譯器才能區(qū)分功能。重載的意義是它可以提高程序的可讀性,因?yàn)槟鸁o(wú)需為同一操作使用不同的名稱(chēng)。

首先由關(guān)鍵字def函數(shù)定義類(lèi)方法,它本質(zhì)上是一個(gè)Python函數(shù),意味著所有def關(guān)鍵字定義的類(lèi)方法,由Python來(lái)解析,因?yàn)镻ython的C底層實(shí)現(xiàn)結(jié)構(gòu)。決定了無(wú)法像原生C/C++那樣可以識(shí)別不同函數(shù)指針

更新中....

最后編輯于
?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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