使用 PyCharm 進(jìn)行代碼生成與重構(gòu)
在工作學(xué)習(xí)中,我們可能會(huì)遇到下面的場(chǎng)景,要編寫一些想似度很高的代碼,或者需要移動(dòng)某個(gè)函數(shù)到其它文件中或者類中,并且希望引用該函數(shù)的代碼都能自動(dòng)更新,如果要解決上述問題,就涉及到代碼生成與重構(gòu)功能。為了提高工作效率,PyCharm 提供了多種生成通用代碼結(jié)構(gòu)和重復(fù)元素的方法,也提供了各種各樣的代碼重構(gòu),可自動(dòng)跟蹤和更正受影響的代碼引用,本節(jié)將介紹與代碼生成與重構(gòu)相關(guān)常用功能。
1. 代碼生成
1.1 使用活動(dòng)模板(Live Template) 生成定制代碼
PyCharm 為許多常見代碼構(gòu)造提供了大量預(yù)定義的 Live Template。我們也可定義自定義模板,以適應(yīng)特定的工作流。
step1:光標(biāo)停留在要展開模板的位置。
step2:輸入模板縮寫,或者打開主菜單 code -> Insert Live Template...
,打開建議列表并選擇需要的模板。如圖所示:自定義模板與 IDE 預(yù)定義的模板都會(huì)顯示在列表里。
1.2 根據(jù)用途生成 Symbols
Python 有不同類型對(duì)象, 像類、方法或者變量。這些對(duì)象都是用字符串符號(hào)代表其名字,根據(jù)用途生成Symbols 就是根據(jù)名字所代表的對(duì)象類型,生成與之匹配的對(duì)象。
step1:引用不存在方法的名稱。IDE高亮顯示引用。按?? (Alt + Enter),然后從建議列表中選擇相應(yīng)的選項(xiàng)。
Tips:一個(gè) Symbol 可能是一個(gè)變量名或者一個(gè)方法名。
step2:選中第一項(xiàng),如圖所示, Write 方法自動(dòng)添加到 People 類 。
1.3 重寫超類的方法
step1:依然是上面的例子,Student 是 People 子類,現(xiàn)在想重寫父類的 speak 方法。主菜單:Code -> Override methods
或者右鍵單擊 類 Student 代碼塊中的任意位置,點(diǎn)擊 Generate
, 然后選擇 Override methods
,在彈出列表中選擇要重寫的方法。
step2:單擊ok, 生成新的代碼。
1.4 實(shí)現(xiàn)接口或抽象類的方法
step1:Skills是個(gè)抽象類,定義了 Write 與 Read 兩個(gè)方法, Junior 是 Skills 子類,現(xiàn)在需要實(shí)現(xiàn)抽象方法。主菜單:Code -> Implement Methods
或者右鍵單擊 類 Junior 代碼塊中的任意位置,點(diǎn)擊 Generate
, 然后選擇 Implement Methods
,在彈出列表中選擇要實(shí)現(xiàn)的方法。
Tips: 如果有多個(gè)方法需要實(shí)現(xiàn),可以一次同時(shí)選擇多個(gè)方法(按住Shift)
step2:單擊ok, 生成新的代碼。
1.5 自動(dòng)生成 Surround code 代碼片段
所謂 Surround code 就是像if…else , do…while and for loops 以及try…catch…finally這樣的語句。PyCharm 提供了基于這種代碼片段的標(biāo)準(zhǔn)模板。
step1: 光標(biāo)停留在某條語句末尾。
step2: 主菜單 Code -> Surround With
或者 ? ?T ( Alt + Ctrl + T)
step3: 從列表中選擇需要的語句。
step4:比如選擇 try / except, 相應(yīng)的語句自動(dòng)生成。
2. 代碼重構(gòu)
代碼重構(gòu)是在不改變代碼外在行為的前提下對(duì)代碼做出修改,以改進(jìn)代碼的內(nèi)部結(jié)構(gòu)的過程。 PyCharm提供了各式各樣的重構(gòu),下面將介紹一些常用的重構(gòu)方法。
2.1 代碼重構(gòu)基本步驟
step1:選擇要重構(gòu)的代碼片段。
step2:在主菜單 Refactor -> Refactor This ...
或所選內(nèi)容的上下文菜單中(擊右鍵),選擇Refactor
。
step3:在打開對(duì)話框會(huì)列出所有重構(gòu)項(xiàng)目,指定重構(gòu)選項(xiàng)(比如:Change Signature…)。在彈出窗口執(zhí)行更改,若要立即應(yīng)用更改,請(qǐng)單擊"Refactor"。
Tips: 對(duì)于某些重構(gòu),可以選擇在實(shí)際執(zhí)行重構(gòu)之前預(yù)覽更改。在這種情況下,"預(yù)覽"按鈕在相應(yīng)的對(duì)話框中可用。
step4:點(diǎn)擊 “Refactor”, 返回到編輯器,代碼已經(jīng)被自動(dòng)更新了。
2.2 更改簽名
更改簽名重構(gòu)包括以下幾種情況:
- 更改函數(shù)名稱;
- 添加、刪除和重新排序參數(shù) ( 上面的例子就是這種情況);
- 將默認(rèn)值分配給參數(shù)。
更改函數(shù)簽名時(shí),PyCharm 會(huì)搜索函數(shù)的所有用法,通常調(diào)用函數(shù)的簽名會(huì)相應(yīng)地更改,同時(shí),這些更改還取決于為新參數(shù)設(shè)置的默認(rèn)值。
2.3 轉(zhuǎn)換為包和模塊
PyCharm 允許 Python 模塊轉(zhuǎn)換為 Python 包,反之也可以。
step1:選擇一個(gè) .py 文件, 比如 “test.py
”;
step2:主菜單 Refactor -> Convert to Python Package
或者 選擇文件擊右鍵,如下圖所示:
step3:查看項(xiàng)目, 創(chuàng)建名為轉(zhuǎn)換模塊的包 (test), __init__.py 文件包含來自 .py 文件的所有代碼。
Tips:創(chuàng)建包后,通常需要修改 init.py 文件,添加包的一些初始化代碼。也可以向其添加更多新模塊。
2.4 移動(dòng)和復(fù)制重構(gòu)
移動(dòng)重構(gòu)可以項(xiàng)目中移動(dòng)類、函數(shù)、模塊、文件和目錄。PyCharm 會(huì)跟蹤這些改變,并自動(dòng)更正源代碼中對(duì)移動(dòng)對(duì)象的所有引用。
將文件或目錄移動(dòng)到其他目錄
- 在"Project"工具窗口中選擇文件或目錄;
- 從主菜單或擊右鍵在上下文菜單中選擇
Refactor -> Move File...
; - 在"To directory"字段中,指定要將所選文件或文件夾移動(dòng)到的文件夾。從列表中選擇現(xiàn)有文件夾,或鍵入要?jiǎng)?chuàng)建的父文件夾的完整路徑。
Tips:在選定文件后, 也可以在"Project"工具窗口中,按住 Ctrl,然后將選擇的文件拖動(dòng)到目標(biāo)位置。
移動(dòng)頂層符號(hào)(symbols)
所謂頂層符號(hào)是頂格定義對(duì)象,像類、函數(shù)或變量,以及main 函數(shù)定義的變量。這些對(duì)象都可以移到
其它文件里。
- 在編輯器打開文件,將光標(biāo)停留在某個(gè)頂層函數(shù)聲明處;
- 從主菜單或擊右鍵在上下文菜單中選擇
Refactor -> Move...
; - 在彈出對(duì)話框中,選擇要移動(dòng)的成員,并指定目標(biāo)文件;
- 點(diǎn)擊 Refactor, 函數(shù)移動(dòng)到新文件。
移動(dòng)函數(shù)/方法到頂層
- 在編輯器打開文件,將光標(biāo)停留在類方法聲明處。
- 從主菜單或擊右鍵在上下文菜單中選擇
Refactor -> Move...
。 - 在彈出對(duì)話框中,指定目標(biāo)文件。
- 查看移動(dòng)后結(jié)果。
復(fù)制重構(gòu)
復(fù)制重構(gòu)可以在不同的或同一目錄中創(chuàng)建文件或目錄的副本。
- 在 Project 窗口中選擇文件;
- 從主菜單或右鍵在上下文菜單 “Refactor -> Copy File…;
- 在打開的 “Copy” 對(duì)話框中,指定要?jiǎng)?chuàng)建的副本的名稱和位置,然后單擊"Refactor",新的文件就會(huì)被創(chuàng)建在指定目錄下。
Tips:在選擇文件后,上下文菜單里直接選擇 copy->copy
, 然后右鍵點(diǎn)擊目標(biāo)路徑,在上下文菜單選擇 Paste
也會(huì)彈出上面的窗口。
2.5 提取重構(gòu)
提取重構(gòu)使源代碼更易于閱讀和維護(hù)。PyCharm 也提供了不同的方法,包括常量、方法及超類的提取等等。下面以提取方法為例介紹提取重構(gòu)的過程:
- 在編輯器中,選擇要轉(zhuǎn)換為方法或函數(shù)的代碼塊;
- 從主菜單或上下文菜單中選擇 Refactor -> Extract Method…
Tips: 形成方法的代碼片段不一定必須是一組語句。它也可以是代碼中某處使用的表達(dá)式。
- 在打開的"Extract Method"對(duì)話框中,指定新函數(shù)的名稱。
- 查看結(jié)果,所選代碼片段將替換為函數(shù)調(diào)用。
2.6 內(nèi)聯(lián)重構(gòu)
內(nèi)聯(lián)重構(gòu)相當(dāng)于提取重構(gòu)的逆過程。比如上面的方法,內(nèi)聯(lián)方法將方法的正文放入其調(diào)用它demo2方法的主體中。
- 在編輯器中,選擇要轉(zhuǎn)換的方法;
- 從主菜單或上下文菜單中選擇
Refactor -> inline...
; - 在打開的對(duì)話框 “inline method 具體的方法名“ , PyCharm 會(huì)提示選擇是在重構(gòu)后刪除方法聲明還是保持其完好無損。根據(jù)選擇,重構(gòu)結(jié)果會(huì)有所不同。
代碼是需要抽取重構(gòu)還是內(nèi)聯(lián)重構(gòu),要具體問題具體分析,比如一段代碼出現(xiàn)在代碼多處位置,就應(yīng)該有抽取重構(gòu)構(gòu)造新的方法。上面的方法如果被多處調(diào)用,做內(nèi)聯(lián)重構(gòu)也是不合適的。
除此以外,一個(gè)變量只是被簡單的賦值,然后又被其它表達(dá)式使用,那這個(gè)變量可能是冗余的,需要內(nèi)聯(lián)重構(gòu)去掉冗余變量。總之,我們要通過不斷的實(shí)踐學(xué)習(xí)才能在重構(gòu)過程中做出正確的判斷。
2.7 重命名重構(gòu)
使用重命名重構(gòu)更改symbols、文件的名稱以及在整個(gè)代碼中對(duì)它們的所有引用。
- 在"Project"工具窗口中選擇要重命名的文件, 或者在編輯器中選擇一個(gè)要重命名的元素(類名、方法名);
- 從主菜單或擊右鍵在上下文菜單中選擇
Refactor -> Rename...
。
在大項(xiàng)目內(nèi),通常模塊或者公共方法接口的名字都在編碼前事先定義好了,像上面重命名重構(gòu)是極少做的,畢竟涉及很多改動(dòng),風(fēng)險(xiǎn)比較大。如果由于特殊情況需要做,也要在重構(gòu)前,仔細(xì)閱讀所有引用代碼,評(píng)估其風(fēng)險(xiǎn)。
3. 小結(jié)
本節(jié)主要講解了代碼生成與代碼重構(gòu)的相關(guān)功能。代碼生成更多功能的是幫助開發(fā)人員提高開發(fā)效率,在大多數(shù)情況下,還是需要在自動(dòng)生成代碼基礎(chǔ)上修改完善的。而代碼重構(gòu)更多的是保證代碼在完成基本功能前提下,更好的使代碼具有更好的適應(yīng)性與可讀性,難點(diǎn)是分析哪些代碼需要重構(gòu),這依賴于編寫大量代碼后的經(jīng)驗(yàn)積累,所以,多寫代碼做更多項(xiàng)目才能逐漸掌握相關(guān)的知識(shí)。