c++轉python

來源:互聯網
上載者:User

        前兩天有個一萬多行的C++項目需要轉PYTHON,邏輯非常複雜,要想看懂邏輯再用PYTHON寫一遍預期時間比直接轉要長,所以大家決定轉PYTHON,遇到一些坑,這裡簡記一下。

        最大的坑是資料結構,PYTHON沒有數組,只能用LIST,C++的函數裡數組直接傳地址進去,可以進行各種操作,尤其是二維數組。PYTHON只能用LIST,二維數組只能嵌套LIST。C++可以傳一個類對象的引用進一個函數。PYTHON得把這個類對象傳進去,改變以後再傳出來外面還得再=一下。其實PYTHON也可以傳引用。傳引用進一個函數注意事項:
1、不能在函數內部使用param = []或者param = list_other
2、不能在調用處傳param + 3之類的
出現第2種情況時,可以使用一個零時arg_param = param[3:]使用arg_param傳入然後函數調用出來以後再迴圈把值賦到原來的parm裡。當然如果是const最好了,返回以後外面就不用再賦值了。

小技巧:第一步:先把C++代碼翻譯成“類似PYTHON的C++"中間代碼。第二步:把這種中間代碼翻譯成PYTHON。第一步走完以後可以進行一次邏輯回測,看是否還能正常工作。

小技巧:第一步中盡量把傳的數組能CONST的統統CONST掉,這其實是C++的編輯習慣問題,盡量養成能CONST的(無論傳指標還是引用)都CONST。這樣PYTHON就可以非常放心的直接傳引用進去,裡面不改變即可。

小技巧:CopyMemory拷貝數組,統統改成:

template<class T>static void CopyMemory_py(T dest[], const T from[], int count, int offset1 = 0, int offset2 = 0){for (int nIdx = 0;nIdx < count;++nIdx){dest[offset1 + nIdx] = from[offset2 + nIdx];}}
def CopyMemory_py(dest, src, count, offset1 = 0, offset2 = 0):    for nIdx in range(count):        dest[offset1 + nIdx] = src[offset2 + nIdx]

當然了,這裡嚴格要求兩個類型是一樣的,如果不一樣可以加個模板參數。
小技巧:所有的數組,在定義的時候,直接把它初始化成固定長度。

def constructArray1(array, count):    for i in range(count):        array.append(0)def constructArray2(array, count1, count2):    for i in range(count1):        tmparray = []        for j in range(count2):            tmparray.append(0)        array.append(tmparray)
小技巧:C++的POD調用memset置空的,統統在裡面封一個clear()函數,把裡面的東西置空。完了C++ PYTHON分別實現一下clear()
小技巧:封掉c++ POD 的 copy construtor、assign construtor,直接private掉。或者檢查一下看有沒有用到的
private:tagStackHandCardInfo& operator=(const tagStackHandCardInfo& rhs);tagStackHandCardInfo(const tagStackHandCardInfo& rhs);
小技巧:拷貝數組,封成函數
// 相容python,傳兩個引用進來,一個賦值給另一個static void tagOutCardTypeResult_copy(tagOutCardTypeResult& lhs, const tagOutCardTypeResult& rhs){lhs.cbCardType = rhs.cbCardType;lhs.cbCardTypeCount = rhs.cbCardTypeCount;for (int nIdx = 0;nIdx < MAX_TYPE_COUNT;++nIdx){lhs.cbEachHandCardCount[nIdx] = rhs.cbEachHandCardCount[nIdx];}for (int i = 0;i < MAX_TYPE_COUNT;++i){for (int j = 0;j < MAX_COUNT;++j){lhs.cbCardData[i][j] = rhs.cbCardData[i][j];}}}
def tagOutCardTypeResult_copy(lhs, rhs):    lhs.cbCardType = rhs.cbCardType    lhs.cbCardTypeCount = rhs.cbCardTypeCount    for nIdx in range(MAX_TYPE_COUNT):        lhs.cbEachHandCardCount[nIdx] = rhs.cbEachHandCardCount[nIdx]    for i in range(MAX_TYPE_COUNT):        for j in range(MAX_COUNT):            lhs.cbCardData[i][j] = rhs.cbCardData[i][j]
小技巧:python中的類中的函數調用,統統要加上self.,可以三步走:step1,文本替換"FuncName"=>"self.FuncName"。step2,文本替換"self.self.FuncName"=>"self.FuncName"(這一步其實是走到中間我才想到的,前面有些函數已經寫成了self.FuncName,經過第一步後會變百self.self.FuncName,所以加上這一步容錯)。step3,文本替換"def self.FuncName"=>"def FuncName"

小技巧:在全部工作開始之前,把所有的函數調用關係理一下。這裡我想到一個比較笨的辦法,用OFFICE PROJECT把每一個函數定義為一個任務,把該函數調用的其他函數設定為它的前置任務,這樣就可以順利的得到一個翻譯的順序圖:

再根據這個圖,得到函數的翻譯順序:

GetCardTypeSortCardListRandCardList            RemoveCard              IsValidCard             GetCardLogicValue       CompareCardMakeCardData            AnalysebCardDataAnalysebDistributing    SearchOutCardASearchOutCardBGetAllBomCardGetAllLineCardGetAllThreeCardGetAllDoubleCardGetAllSingleCardAnalyseOutCardTypeAAnalyseOutCardTypeBCombination             Permutation             AnalyseSinleCardCountSetUserCardSetBackCardSetLandScoreCardDataRemoveUserCardDataBankerOutCardABankerOutCardBUpsideOfBankerOutCardAUpsideOfBankerOutCardBUndersideOfBankerOutCardAUndersideOfBankerOutCardBLandScoreL2C                     _TestOutAllCardAnalyseFourCardTypeTestOutAllCardIsLargestCardVerifyOutCard                        
從左至右,就是翻譯順序。
小技巧:C++程式員有時候喜歡界定局部變數,或者只是為了邏輯清晰,使用兩個花括弧括起來寫一段代碼,python直接使用 if True:來保證對齊

小技巧:如果你準備翻譯的C++代碼不是非常整潔,可以使用VISUAL STUDIO格式化一下 CTRL A全選,CTRK K F即可。這一步可以省掉很多事情,因為PYTHON對齊是需要非常小心的。典型的就是類似這樣的c++代碼:

for(int nIdx = 0;nIdx < nCount;++nIdx)    do_something(some_param1, some_param2);    do_someotherthing(some_param3, some_param4);
如果只有這兩行相信正常人一眼就能看見,但是如果下面的拖的非常長,又或者
do_something
函數前面後面跟了花括弧,裡面東西又非常長,這時候後面的代碼是極不容易被發現對齊問題的。

小技巧:在遞迴函式或者是需要注意效能的函數中,數組可以加上位移來實現c++ 中類似array + 3這樣的用法的python版:

//原函數:void Func(int array[]){    if (...)        Func(array + 3);    ......}//新函數void Func(int array[], int offset = 0){    if (...)    Func(array, offset + 3);}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.