日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

代码模板引擎

發(fā)布時間:2024/5/14 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 代码模板引擎 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

功能介紹

mkTpl是一個基于Python編寫的模板引擎包. 初始版本發(fā)布于2017年, 當(dāng)時開發(fā)該模板引擎是為了在嵌入式儀表開發(fā)過程中梳理軟件配置, 以便可以生成配置代碼, 避免手動整理配置參數(shù), 極大提升開發(fā)工作效率. 后續(xù)開發(fā)過程中有幾次不同程度的優(yōu)化升級, 引入了用戶字定義代碼與函數(shù)功能, 拓展了模板引擎的應(yīng)用范圍, 目前mkTpl包已在多個項目中引用, 對開發(fā)效率有顯著提升.

環(huán)境搭建

  • 安裝python version > 3.0以上版本
  • 安裝mkTpl軟件包
  • 安裝需要使用的軟件包(xlrd/PyYAML/xml等, 未使用可不安裝)

代碼實例

import mkTplctx = {'測試1': 12345, '測試2': 67890} template = {'test.tpl.c': ['./tpl', './gen', 'test.gen.c']}# 實例化模板引擎 tplobj = mkTpl.mktpl() # 加入數(shù)據(jù)庫 tplobj.addlib('ctx', ctx) # 導(dǎo)入模板, 生成代碼 tplobj.setTemplate(template)

模板語法

在代碼實例中字典template有一個值: test.tpl.c, 這里的test.tpl.c就是需要生成的代碼模板, 只有導(dǎo)入了模板, 代碼引擎才能根據(jù)模板和數(shù)據(jù)庫導(dǎo)出用戶需要的代碼. 模板需要提供所在位置與生成代碼存放位置以及生成代碼文件名, 模板引擎實際不會關(guān)注生成的文件格式, 這里只依賴用戶定義, 理論上可以生成任意用戶定義的文本文件.

針對模板的格式有一定要求, 只有按照要求定義的模板, 模板引擎才能解析. 實際代碼生成的過程可以理解成對文件的讀寫過程, 單獨對文件讀寫大家應(yīng)該都接觸過, 如下實例:

# 以a+屬性打開一個文件 text.c file = open('text.c', a+)# 讀取文本內(nèi)容 lines = file.readlines()# 寫入hello world! file.write('hello world!')file.close()

而模板引擎的作用就是解析模板, 生成文件讀寫的代碼, 再運行生成的代碼即可獲得想要的最終目標(biāo)代碼. 這里很有意思, 代碼并不是事先寫好的, 而是模板引擎寫的. Python是一門解釋性的語言, 剛好可以完成上述的功能.

  • 模板實例: test.tpl.c
// 1. 靜態(tài)代碼 void VfcMgr_vMain(void) {// user code. } // 2. 可迭代模式 <%test_sb = ['test0', 'test1']%> <%for i in range(0, len(test_sb)):%> <% User Coding Symbol: @test_sb[i]%> // 3. 單例模式 <%User Coding Symbol: test3%> // 4. 參數(shù)導(dǎo)入模式 <%for key in ctx:%> <% ~test coding: ${key}, ${ctx[key]}%>
  • 生成代碼: test.gen.c
// 1. 靜態(tài)代碼 void VfcMgr_vMain(void) {// user code. } // 2. 可迭代模式 /*********************************************************************************************************************** DO NOT CHANGE THIS COMMENT! << Start of user code implementation >> DO NOT CHANGE THIS COMMENT!* Symbol: test0*********************************************************************************************************************/隨意輸入 /*********************************************************************************************************************** DO NOT CHANGE THIS COMMENT! << End of user code implementation >> DO NOT CHANGE THIS COMMENT!*********************************************************************************************************************/ /*********************************************************************************************************************** DO NOT CHANGE THIS COMMENT! << Start of user code implementation >> DO NOT CHANGE THIS COMMENT!* Symbol: test1*********************************************************************************************************************/隨意輸入 /*********************************************************************************************************************** DO NOT CHANGE THIS COMMENT! << End of user code implementation >> DO NOT CHANGE THIS COMMENT!*********************************************************************************************************************/ // 3. 單例模式 /*********************************************************************************************************************** DO NOT CHANGE THIS COMMENT! << Start of user code implementation >> DO NOT CHANGE THIS COMMENT!* Symbol: test3*********************************************************************************************************************/隨意輸入 /*********************************************************************************************************************** DO NOT CHANGE THIS COMMENT! << End of user code implementation >> DO NOT CHANGE THIS COMMENT!*********************************************************************************************************************/ // 4. 參數(shù)導(dǎo)入模式 test coding: 測試1, 12345 test coding: 測試2, 67890

函數(shù)

在<%%>中定義函數(shù), 以def起始的代碼會默認(rèn)識別為函數(shù)定義, 函數(shù)直到出現(xiàn)一行靜態(tài)代碼結(jié)束. 在定義函數(shù)時, 函數(shù)存在一個默認(rèn)參數(shù)info, 在不使用輸出文件功能時可不定義, 若定義參數(shù)info使用的時候需要加上參數(shù)info, 其他用戶參數(shù)可自行定義, 實例如下:

函數(shù)定義: <%def test_func(info):%> <% print("hello world.")%> <% ~write in output file: hello world.%>函數(shù)使用: <%test_func(info)%>

特殊標(biāo)識 <%%>

模板語法動態(tài)模板代碼完全支持python語法, 但動態(tài)代碼需要使用<%%>標(biāo)記, 否則默認(rèn)為靜態(tài)代碼.

example:

<%for key in ctx:%> <% print('ctx key: %s'% key)%>

特殊標(biāo)識: ~ (info.write)

example:

<%for key in ctx:%> <% ~test coding: ${key}, ${ctx[key]}%>or<%for key in ctx:%> <% info.write("test coding: %s, %s\n"%(key, ctx[key]))%>

實例中給出了兩段代碼, 實際結(jié)果是一樣的, ~ 與 info.write 擁有相同功能, ~是優(yōu)化后的表現(xiàn), 使模板編輯更方便高效.

關(guān)鍵字: User Coding Symbol

User Coding Symbol字段設(shè)計的時候參考了DaVinci生成代碼的功能, 生成代碼的時候可以識別User Coding Symbol字段, 在該字段注釋內(nèi)部用戶可以編寫自定義代碼, 模板引擎會主動merge用戶代碼與生成的代碼, 該功能的引入, 有效的擴(kuò)大了mkTpl的應(yīng)用范圍, 有了該功能后, 再不局限于設(shè)計之初的想法, 不但能應(yīng)用于配置代碼的生成, 也可應(yīng)用于大量重復(fù)邏輯代碼的編寫中. 實際開發(fā)過程中往往會遇到結(jié)構(gòu)類似, 但是細(xì)節(jié)上又存在一些不確定性的差異, 原來的模板引擎功能很難實現(xiàn)這種代碼的整理, 引入User Coding Symbol后, 使得該場景下的模板實現(xiàn)成為可能.

在使用User Coding Symbol的時候需要注意, 實際有兩種方式使用:

  • 單例模式

<%User Coding Symbol: name%>
適用于單個User Coding Symbol

  • 迭代模式

<%User Coding Symbol: @nameVar%>
適用于多個User Coding Symbol

特殊標(biāo)識: ${}

${}最常用, 變量的替換需要使用${}標(biāo)記, 變量放入大括號內(nèi), 變量之前可以帶數(shù)字, 用于定義寫入字符長度與對其功能(正負(fù)分別表示不同方向的對其).

<% ~test coding: ${10key}, ${-6ctx[key]}%>

使用實例

在儀表項目中, Warning與VfcMgr模塊中應(yīng)用mkTpl做了部分代碼生成工作, 以VfcMgr為例, 應(yīng)用過程如下:

在VFC功能開發(fā)中, 有眾多的Activator, 每個都包含大量的信號邏輯判斷功能, 為了解決開發(fā)者在這樣巨量的邏輯中迷失, 引入yaml配置邏輯功能, 所有相關(guān)的信號邏輯表達(dá)式全部在yaml文件上統(tǒng)一配置. 再配合部分靜態(tài)代碼, 實現(xiàn)邏輯功能全配置, 不用用戶單獨編寫額外代碼.

有關(guān)LC -> VFC -> PNC之間的關(guān)系通過excel配置, 再由mkTpl加上模板一并導(dǎo)出關(guān)系配置表.

yaml配置實例:

ObjMntr:PinToDrvForHmiCen: # VFC Activation Criteria# ( {PinToDrvCod}ChangeFromAnyToX (X=CodVld.Inact_Active) )# OR( {PinToDrvCodHmiReq}ChangeToOther ) )# AND{VehModMngtGlbSafe1}NotEqualToX(X=UsgModSts.UsgModSts1_UsgModAbdnd) )# VFC Deactivation Criteria# ( VFCTimeOutDelay [sec] = 3 )Delay: 3000Tx:PinToDrvCodCodVld:Type: uint8Condition: [ Prev.PinToDrvCodCodVld != Curr.PinToDrvCodCodVld, Curr.PinToDrvCodCodVld == Inact_Active ]PinToDrvCodHmiReq:Type: PinToDrvCodHmiReqCondition: [ Prev.PinToDrvCodHmiReq != Curr.PinToDrvCodHmiReq ]LogicalExpression:ActyLE0: CC_PinToDrvCodCodVld_Condition_0 && CC_PinToDrvCodCodVld_Condition_1ActyLE1: CC_PinToDrvCodHmiReq_Condition_0ActRule: LE_ActyLE0 || LE_ActyLE1

yaml軟件模板:

/*** Tx signals interface.*/ <%sigsTab = []%> <%for lc in mrkChgMap['ObjMntr']:%> <% if 'Tx' in mrkChgMap['ObjMntr'][lc]:%> <% for sg in mrkChgMap['ObjMntr'][lc]['Tx']:%> <% a = False%> <% if sg not in sigsTab:%> <% sigsTab.append(sg)%> <% if sg in sglib['sg']['tx']:%> <% a = True%> <% ~#define VfcMgr__Read_Write_${sg}() (SigSer_${sg})%> <% for gp in sglib['gp']['tx']:%> <% if sg in sglib['gp']['tx'][gp]:%> <% a = True%> <% if sglib['gp']['tx'][gp][sg]['index'] != -1:%> <% ~#define VfcMgr__Read_Write_${sg}() (SigSer_${gp}[${sglib['gp']['tx'][gp][sg]['index']}])%> <% else:%> <% ~#define VfcMgr__Read_Write_${sg}() (SigSer_${gp}.${sg})%> <% else:%> <% a = True%> <% if a == False:%> <% print("Sg: %s is error."%sg)%> ...

yaml生成代碼:

#define VfcMgr__nTimeoutDly_PinToDrvForHmiCen ( (uint16)(3000ul / VfcMgr__nMainCycleCntr) )#define VfcMgr__Read_Write_PinToDrvCodCodVld() (SigSer_PinToDrvCod.PinToDrvCodCodVld) #define VfcMgr__Read_Write_PinToDrvCodHmiReq() (SigSer_PinToDrvCodHmiReq)#define VfcMgr__boPinToDrvForHmiCen_PinToDrvCodCodVld_Condition_0 ( VfcMgr__PinToDrvCodCodVld != VfcMgr__Read_Write_PinToDrvCodCodVld() ) #define VfcMgr__boPinToDrvForHmiCen_PinToDrvCodCodVld_Condition_1 ( VfcMgr__Read_Write_PinToDrvCodCodVld() == Inact_Active ) #define VfcMgr__boPinToDrvForHmiCen_PinToDrvCodHmiReq_Condition_0 ( VfcMgr__PinToDrvCodHmiReq != VfcMgr__Read_Write_PinToDrvCodHmiReq() )#define VfcMgr__boPinToDrvForHmiCen_ActyLE0 ( VfcMgr__boPinToDrvForHmiCen_PinToDrvCodCodVld_Condition_0 && VfcMgr__boPinToDrvForHmiCen_PinToDrvCodCodVld_Condition_1 ) #define VfcMgr__boPinToDrvForHmiCen_ActyLE1 ( VfcMgr__boPinToDrvForHmiCen_PinToDrvCodHmiReq_Condition_0 )#define VfcMgr__boActRule_PinToDrvForHmiCen ( VfcMgr__boPinToDrvForHmiCen_ActyLE0 || VfcMgr__boPinToDrvForHmiCen_ActyLE1 )

excel配置:

excel軟件模板:

<%~const VfcMgr__tstLCsAttrs VfcMgr__rastLCsAttrs_Tab[VfcMgr_nenNrOfLCs] = {%> <%for lc in VFCInfo:%> <% u8VFCIndex = str(VFC2PNC[VFCInfo[lc]['VFCName']]['VFCID'] + 100)[1:]%> <% u8PNCIndex = str(VFC2PNC[VFCInfo[lc]['VFCName']]['PNC'] + 100)[1:]%> <% na = lc.replace('-', '')%> <% na = na.replace(' ', '')%> <% u8UsageMode = VFCInfo[lc]['Usagemode']%> <% u8CarMode = VFCInfo[lc]['CarMode']%> <% pfLCActyFnct = 'VfcMgr__v'+na+'Detect'%> <% ~ {VfcMgr_nVFC${u8VFCIndex}, VfcMgr_nPNC${u8PNCIndex}, ${3u8UsageMode}, ${3u8CarMode}, ${-52pfLCActyFnct}}, /*!> ${lc} */%> };

excel生成代碼:

const VfcMgr__tstLCsAttrs VfcMgr__rastLCsAttrs_Tab[VfcMgr_nenNrOfLCs] = {{VfcMgr_nVFC41, VfcMgr_nPNC16, 7, 31, VfcMgr__vV2XCtrlForHmiCenDetect }, /*!> V2XCtrlForHmiCen */{VfcMgr_nVFC41, VfcMgr_nPNC16, 15, 31, VfcMgr__vDrvrHmiMgrPlatform1ForDrvrHmiDetect }, /*!> DrvrHmiMgrPlatform1ForDrvrHmi */{VfcMgr_nVFC41, VfcMgr_nPNC16, 15, 31, VfcMgr__vDrvrHmiMgrPlatform2ForDrvrHmiDetect }, /*!> DrvrHmiMgrPlatform2ForDrvrHmi */{VfcMgr_nVFC41, VfcMgr_nPNC16, 15, 31, VfcMgr__vInfotainmentModMgr_InfotainmentPushDetect }, /*!> InfotainmentModMgr_InfotainmentPush */{VfcMgr_nVFC41, VfcMgr_nPNC16, 7, 9, VfcMgr__vVehSurrndgsVisnCtrlDetect }, /*!> VehSurrndgsVisnCtrl */{VfcMgr_nVFC41, VfcMgr_nPNC16, 15, 9, VfcMgr__vVehSurrndgsVisnAddlDetect }, /*!> VehSurrndgsVisnAddl */{VfcMgr_nVFC41, VfcMgr_nPNC16, 15, 31, VfcMgr__vFaceIdnMgrDetect }, /*!> FaceIdnMgr */{VfcMgr_nVFC16, VfcMgr_nPNC17, 15, 31, VfcMgr__vLeReCenLockUnlockBtnDetect }, /*!> LeReCenLockUnlockBtn */{VfcMgr_nVFC16, VfcMgr_nPNC17, 31, 31, VfcMgr__vRiReCenLockUnlockBtnDetect }, /*!> RiReCenLockUnlockBtn */{VfcMgr_nVFC10, VfcMgr_nPNC18, 7, 31, VfcMgr__vExteriorLightShow_ExteriorLightingDetect }, /*!> ExteriorLightShow_ExteriorLighting */{VfcMgr_nVFC10, VfcMgr_nPNC18, 15, 31, VfcMgr__vWelcomeLightDIYDetect }, /*!> WelcomeLightDIY */{VfcMgr_nVFC21, VfcMgr_nPNC19, 31, 31, VfcMgr__vLePwrSldgDoorBtnDetect }, /*!> LePwrSldgDoorBtn */{VfcMgr_nVFC21, VfcMgr_nPNC19, 31, 31, VfcMgr__vRiPwrSldgDoorBtnDetect }, /*!> RiPwrSldgDoorBtn */{VfcMgr_nVFC21, VfcMgr_nPNC19, 15, 31, VfcMgr__vLockgCtrlForHmiCen_PowerClosuresDetect }, /*!> LockgCtrlForHmiCen_PowerClosures */{VfcMgr_nVFC21, VfcMgr_nPNC19, 15, 31, VfcMgr__vPwrDoorCtrlForHmiCen_PowerClosuresDetect }, /*!> PwrDoorCtrlForHmiCen_PowerClosures */{VfcMgr_nVFC21, VfcMgr_nPNC19, 15, 31, VfcMgr__vActvReSplrForHmiCenDetect }, /*!> ActvReSplrForHmiCen */ };

總結(jié)

以上是生活随笔為你收集整理的代码模板引擎的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。