[69→100]用Python自動生成java類

隨著公司的并行項目越來越多,Android新項目初始化的變成一個問題,一開始是每個人建立項目不一樣,為此設計了清單列表。后來發(fā)現(xiàn)項目是一致了,但是每次都要手動執(zhí)行列表,大部分都是簡單地新建文件,很無聊,而且偶爾思想開個小差,還出錯,又要找問題、修bug,煩~。
都說懶惰是程序員的優(yōu)良品質(zhì),所以決定研究一下怎么自動化整個過程。

需求

經(jīng)過分析,發(fā)現(xiàn)這里面最核心需求有兩個:

  1. 根據(jù)模板java文件生成最終的java文件,主要是替換類名包名app包名
  2. 根據(jù)包名規(guī)則生成相應的文件夾。

其中涉及的流程有:

  1. 讀取、解析配置文件;
  2. 根據(jù)名稱,生成相應的文件夾;
  3. 根據(jù)模板文件,生成文件夾下相應的文件;

涉及的技術點有:

  1. 配置文件的格式用什么好?
  2. 怎么解析配置文件?

技術點1:配置文件的格式用什么好?

經(jīng)過分析,考慮擴展性和簡潔程序,決定json來寫配置。

方案一:json和文件(夾)的層級結(jié)構(gòu)保持一致。

  1. type:這一層級的類型:
  • dir: 表示文件夾
  • file: 表示文件
  1. 如果 type為dir,則需要定義:
  • name:文件夾的名字
  • list:子文件(夾)列表
  • package_name:包名。默認為 父級文件夾名字和自身文件夾的名字的疊加。
  1. 如果 type為file,則需要定義:
  • name:文件的名字
  • template:模板文件的名字

這樣一個配置兩個文件的json如下:

{
    "type":"dir",
    "name":"baby",
    "list":[
        {
            "type":"dir",
            "name":"view",
            "list":[
                {
                    "type":"file",
                    "name":"BabyFragment",
                    "template":"BaseFragment.java.tpl"
                },
                {
                    "type":"file",
                    "name":"MorningCheckFragment",
                    "template":"BaseFragment.java.tpl"
                }
            ]
        }
    ]
}

才兩個文件,就有三層嵌套,就算是增加同包文件,都要增加三行,太繁瑣了。換一種思路:

方案二:根據(jù)模板、包名,把同一個包名下的同一個模板的文件匯總在一起

  1. 第一層:
  • app_id: 應用包名
  • list: 模板新建列表
  1. 第二層:模板新建列表項
  • package_name: 對應的包名
  • template: 采用的模板
  • fileList: 需要新建的文件列表

這樣json變成如下:

{
  "app_id":"panda.android.test",
  "list":[
      {
          "package_name":"panda.android.test",
          "template":"BaseFragment.java.tpl",
          "fileList":[
              "BabyFragment",
              "MorningCheckFragment"
          ]
      }
  ]
}

簡單直觀很多。

怎么解析配置文件?

這里當然選擇強大易用的Python了。
Python字符串替換的3種方法:

1. 字符串替換

將需要替換的內(nèi)容使用格式化符替代,后續(xù)補上替換內(nèi)容;

template = "hello %s , your website is %s " % ("簡書","http://www.lxweimin.com/")
print(template)

也可使用format函數(shù)完成:

template = "hello {0} , your website is {1} ".format("簡書","http://www.lxweimin.com/")
print(template)

2. 字符串命名格式化符替換

使用命名格式化符,這樣,對于多個相同變量的引用,在后續(xù)替換只用申明一次即可;

template = "hello %(name)s ,your name is %(name), your website is %(message)s" %{"name":"簡書","message":"http://www.lxweimin.com/"}
print(template)

使用format函數(shù)的語法方式:

template = "hello {name} , your name is {name}, your website is {message} ".format(name="大CC",message="http://blog.me115.com")
print(template)

3. 模版方法替換

使用string中的Template方法;

from string import Template
tempTemplate = string.Template("Hello $name ,your website is $message")
print(tempTemplate.substitute(name='大CC',message='http://blog.me115.com'))

有了模版方法后,就可以將模版保存到文件單獨編輯,在生成的地方替換為需要的變量。

樣例代碼

  1. BaseFragment.java.tpl如下:
package ${PACKAGE_NAME};
import ${ANDROID_APP_ID}.R;
import panda.android.lib.base.ui.fragment.BaseFragment;
/**
 * Created on ${DATA}.
 */
public class ${CLASS_NAME} extends BaseFragment{
    @Override
    public int getLayoutId() {
        return R.layout.fragment_net;
    }
}
  1. 配置文件如下:
{
  "app_id":"panda.android.test",
  "list":[
      {
          "package_name":"panda.android.test",
          "template":"BaseFragment.java.tpl",
          "fileList":[
              "BabyFragment",
              "MorningCheckFragment"
          ]
      }
  ]
}
  1. 腳本如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os,sys,re,traceback
from datetime import datetime
from string import Template
import json
def generateAndroidJavaCode(app_id, package_name, template, fileName):
    className = fileName;
    path = "./" + package_name.replace('.','/');
    filePath = r'%s/%s.java' % (path,className)
    if os.path.exists(path) == False:
        os.makedirs(path)
    class_file = open(filePath,'w')
    lines = []
    #模版文件
    template_file = open(r'BaseFragment.java.tpl','r')
    tmpl = Template(template_file.read())
    #模版替換
    lines.append(tmpl.substitute(
                PACKAGE_NAME = package_name,
                ANDROID_APP_ID = app_id,
                DATA = datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                CLASS_NAME = className))
    # 0.將生成的代碼寫入文件
    class_file.writelines(lines)
    class_file.close()
    print 'generate %s over. ~ ~' % filePath
## 1. 解析配置文件
configuration = """
{
  "app_id":"panda.android.test",
  "list":[
      {
          "package_name":"panda.android.test",
          "template":"BaseFragment.java.tpl",
          "fileList":[
              "BabyFragment",
              "MorningCheckFragment"
          ]
      }
  ]
}
"""
configurationJson = json.loads(configuration);
## 2. 按照模板生成對應的文件
app_id =  configurationJson["app_id"]
for filesInfo in configurationJson["list"]:
    package_name = filesInfo["package_name"]
    template = filesInfo["template"]
    for fileName in filesInfo["fileList"]:
        generateAndroidJavaCode(app_id, package_name, template, fileName);
  1. 最后生成的文件如下:


引用

  1. python 自動生成C++代碼 (代碼生成器)

Panda
2016-07-04

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,414評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,169評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,722評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,465評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,823評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,000評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,554評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,295評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,513評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,722評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,125評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,430評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,237評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,482評論 2 379

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,825評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,727評論 25 708
  • 22年12月更新:個人網(wǎng)站關停,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,205評論 22 257
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,922評論 6 342
  • 潮紅暮色觀閣景 半百知行覽路晴 不惑之年思亂徑 唯心穩(wěn)見夜來臨
    晴天映白云閱讀 179評論 0 0