對于代碼整潔,沒有唯一的或者嚴格的定義,而且可能無法正式地衡量怎樣才算代碼整潔,因此你不能在代碼倉庫上運行一個可以告訴你代碼是好是壞、可維護性如何的工具,當然,你可以運行檢查器、代碼校驗器、靜態分析器等工具,這些工具會給你很大的幫助,它們是必需的,但光有這些還遠遠不夠,代碼整潔與否不是機器或腳本能說了算的(到目前為止),而是作為專業人員的我們才能決定的,

幾十年來,我們沿用“編程語言”這個術語,并將其視為把我們的想法傳達給計算機的語言,可以讓計算機運行我們的程式,但是我們錯了,這僅僅是部分事實,編程語言背后的“真正語言”是將我們的想法傳達給其他開發人員的語言,
這才是代碼整潔的真正本質所在,它取決于其他開發人員是否能夠讀取和維護代碼,作為專業人士,我們是唯一能夠判斷這一點的人,想想看,作為開發人員,我們閱讀代碼的時間比實際撰寫代碼的時間要多得多,每當我們想要更改或添加新功能,首先必須閱讀需要修改或擴展的代碼的所有背景關系內容,編程語言(Python)就是開發人員實作互相溝通的語言,
為什么保持代碼整潔如此重要,原因有很多,大多數原因與可維護性、減少技術債務、有效配合敏捷開發以及管理一個成功的專案的想法有關,
我們想探討的第一個想法是關于敏捷開發和持續交付的,如果希望專案能夠以穩定和可預測的速度不斷成功地交付特性,那么必須有一個良好且可維護的代碼庫,
假設你正駕駛著一輛汽車行駛在去往某個目的地的道路上,而且想要在某個時間點之前到達那里,你必須預估自己到達目的地的時間,這樣才能告知正在等你的人,如果汽車不出故障,道路十分平坦,那么你的預估不大可能有太大的偏差;相反,如果道路被破壞,你必須下車把石頭移開,或者要避開裂縫,抑或每隔幾千米就必須停下來檢查一下發動機等,那么你不太可能確定什么時候到達(或者你是否能到達),這個比喻明確易懂,這里的道路可以理解為代碼,如果希望以穩定、恒定和可預測的速度向前推進專案,那么代碼應該是可維護和可讀的,
技術債務是指因妥協或所做出的不良決策而導致的軟體問題,在某種程度上,我們可以從兩個方面考慮技術債務問題,一是從過去到現在,如果我們當前面臨的問題是由之前撰寫的錯誤代碼造成的,那會怎樣?二是從現在到將來,如果我們決定現在就走捷徑,而不是花時間去尋找合適的解決方案,那么未來又會為自己帶來什么麻煩?
“債務”這個詞用得恰如其分,這是一筆債務,因為在未來代碼將比現在更難以修改,產生的成本就是債務的利息,產生的技術債務意味著,明天修改代碼比今天更困難,成本更高,而且后天的成本會更昂貴,等等,
一旦團隊不能按時交付一些東西,并且不得不停下來去修復和重構代碼,代碼就要付出技術債務的代價,
技術債務最糟糕的一點是它代表了一個長期和根本的問題,這不是什么值得高度警覺的東西,相反,這是一個悄無聲息的問題,這個問題分散在整個專案的各個部分,在某一天,在某一個特定的時間,這個問題會“醒來”,并成為專案推進的阻礙,
1 代碼格式化在代碼整潔中的作用
代碼整潔是指根據一些標準(例如,PEP-8或由專案規范定義的自定義標準)進行的代碼格式化和結構化嗎?并非如此,
代碼整潔遠遠不止編碼標準、格式化、美化工具和其他有關代碼布局的檢查這些內容,代碼整潔是關于實作高質量的軟體和建立一個健壯、可維護和避免技術債務的系統的,一段代碼或整個軟體組件可以百分之百符合PEP-8(或任何其他準則)標準,但仍可能無法滿足上述要求,
然而,不注意代碼的結構會有一些危險,鑒于此,我們先來分析不良代碼結構的問題以及如何解決這些問題,然后介紹如何為Python專案配置和使用工具,以便自動檢查和糾正問題,
綜上所述,我們可以說代碼整潔與PEP-8或編碼風格沒有任何關系,代碼整潔的意義遠不止于此,除了可維護性和軟體的質量,它還意味著更有意義的東西,不過,正如你將看到的,要實作高效作業,正確地格式化代碼非常重要,
2 在專案中遵循編碼風格準則
編碼準則是專案在質量標準下開發時必須考慮的最低要求,在本節中,我們將探討其背后的原因,接下來我們開始探討如何通過工具自動在專案中遵循編碼風格準則,
在試圖考慮在代碼布局中找到某種好的特性時,我們首先想到的就是一致性,我們希望代碼能夠具有一致的結構,以便更易閱讀和理解,如果代碼不正確或者結構不一致,并且團隊中的每個人都以自己的方式做事,那么最終得到的將是需要額外努力和集中精力才能正確理解的代碼,這樣的代碼很容易引起誤解,并且由此引發的漏洞或微小的錯誤很可能被忽略,
上述情況是我們想要避免的,我們想要的是一眼就能讀懂和理解的代碼,
如果開發團隊的成員都同意采用標準化的方式撰寫代碼,那么所得到的代碼看起來會更加熟悉,這樣,你就能快速識別模式,并且記住這些模式,進而能更容易地理解內容和檢測錯誤,例如,當某些代碼出錯時,你可能會在你熟悉的模式中看到一些奇怪的東西——它們會吸引你的注意,再仔細觀察,就很可能發現錯誤!
正如經典著作Code Complete中所述的,在名為Perception in Chess(1973年)的論文中對此進行了有趣的分析,該論文提到了一項實驗,以確定不同的人如何理解或記憶不同的棋局,該實驗針對不同級別的棋手(新手、中級棋手和象棋高手)以及棋盤上不同位置的棋局來進行統計,他們發現,當棋子的位置是隨機的時候,新手能和象棋高手表現得一樣好,因為這只是一個記憶練習,任何人都可以發揮出合理的水平,但當棋子的位置遵循一個可能發生在一場真正對弈中的一些邏輯順序(或者,遵守某種一致性,堅持某種模式時)時,那么象棋高手們的表現比其他人要好得多了,
現在我們想象一下,同樣的情況也適用于軟體開發,作為Python方面的軟體工程師專家,我們就好比上述例子中的象棋高手,如果代碼的結構是隨機的,沒有遵循任何邏輯或者沒有遵循任何標準,我們就會像一個新手開發人員一樣,很難發現錯誤;如果我們習慣以結構化的方式閱讀代碼,并且通過遵循這種模式學會從代碼中快速獲得想法,就會在專案開發中比其他開發人員更有優勢,
就Python而言,你應該遵循的編碼風格是PEP-8,你可以對其進行擴展或采用其中的一部分,以適應正在參與的專案的某種特殊性(如行的長度、字串的注釋等),不過,我們建議,無論你使用最原始版本的PEP-8規范還是對它進行擴展,都應該堅持使用,而不是從頭開始嘗試另一個不同的標準,
這是因為PEP-8充分考慮了Python語法的許多特殊性(通常不適用于其他語言),并且它是由對Python語法做出貢獻的核心Python開發人員創建的,因此,我們認為其他標準其實很難與PEP-8相提并論,更不用說超越它了,
尤其是,在處理代碼時,PEP-8還有一些不錯的改進特性,
(1)可進行grep,這就是在代碼中對內容進行grep的能力,即在某些檔案(以及這些檔案的某個部分)中搜索所要查找的特定字串,PEP-8引入的特性之一是區分將值賦值寫入變數的方式和傳遞給函式的關鍵字引數的方式,
為了更好地理解這一點,我們用一個示例加以闡釋,假設我們正在進行除錯,需要找到名為location的引數值的傳遞位置,我們可以運行以下grep命令,獲悉要查找內容所在的檔案和行號,
$ grep -nr "location=" .
./core.py:13: location=current_location,
現在,我們想知道這個變數在哪里被分配這個值,則可以運行以下命令,
$ grep -nr "location =" .
./core.py:10: current_location = get_location()
PEP-8建立了這樣一種約定,即當通過關鍵字向函式傳遞引數時,不使用空格,但在分配變數時使用空格,因此,我們可以調整搜索條件(第一次搜索時等號兩側沒有空格,第二次搜索時等號兩側都有一個空格),從而提高搜索效率,這是遵守約定的好處之一,
(2)一致性,如果代碼看起來有一種統一的格式,閱讀起來就會容易得多,這對于新加入專案的人來說尤為重要,如果你希望有新的開發人員加入專案,或者為團隊聘用新的(可能經驗不足的)程式員,那么他們勢必要熟悉代碼(甚至可能由多個代碼倉庫組成),如果代碼格式、檔案、命名約定等在所有代碼倉庫的所有檔案中都是相同的,那么他們的作業將變得更加輕松,
(3)代碼質量,以結構化的方式查看代碼,你一下子就能更熟練地理解它(就像在Perception in Chess中所說的那樣),并且更容易發現程式的漏洞和錯誤,除此之外,檢查代碼質量的工具也會提示潛在的錯誤,對代碼的靜態分析可能有助于降低每行代碼的錯誤率,
本文摘自《撰寫整潔的Python代碼》

這是一本關于Python軟體工程原理方面的書,
關于軟體工程的書有很多,關于Python的可用資源也有很多,但要將這兩者結合起來,還有許多作業要做,本書正是嘗試在這二者之間架起一座橋梁,
要想在一本書中涵蓋關于軟體工程的所有主題是不現實的,因為軟體工程的領域十分廣泛,而且針對某個特定的主題會有專門的圖書去介紹,本書重點介紹Python軟體工程的主要實踐和原則,旨在幫助讀者撰寫更易于維護的代碼,同時教讀者利用Python的特性來撰寫代碼,
章節提要
第1章 簡介、代碼格式和工具,介紹搭建Python開發環境所需的主要工具、Python開發人員在開始使用該語言時需要了解的基本知識,以及維護專案中代碼可讀性的一些指導原則,如用于靜態分析、檔案、型別檢查和代碼格式化的工具,
第2章 Python風格代碼,介紹Python中的第一個習慣用法——我們在后續章節中將繼續使用它,本章還會介紹一些Python的獨有特性,以及如何使用它們,并且開始圍繞“Python風格代碼如何能夠讓代碼質量更高”展開論述,
第3章 好代碼的一般特征,回顧軟體工程的一般原則,以期幫助讀者撰寫可維護的代碼,本章就這個話題展開討論,并利用Python語言中的工具應用這些原則,
第4章 SOLID原則,介紹面向物件軟體設計的SOLID原則,SOLID是軟體工程領域的行業術語,即SRP、OCP、LSP、ISP和DIP,本章會展示這5項原則在Python中的應用,可以說,鑒于Python語言的性質,并非所有方法都完全適用,
第5章 用裝飾器改進代碼,介紹Python的最大特性之一——裝飾器,在了解如何創建裝飾器(用于函式和類)之后,我們將其用于代碼重用、責任分離和創建更細粒度的函式,
第6章 用描述符從物件中獲取更多資訊,探討Python中的描述符,它把面向物件設計提升到了一個新的層次,盡管這更多只是一個與框架和工具相關的特性,但我們可以看到如何用描述符提高代碼的可讀性,以及如何重用代碼,
第7章 使用生成器,說明生成器可能是Python的最佳特性,事實上,迭代是Python的核心組件,這讓我們認為它引申出了一種新的編程范式,一般來說,通過使用生成器和迭代器,我們可以考慮撰寫程式的方式,基于從生成器中吸取的知識,我們將進一步了解Python中的協同程式以及異步編程的基本知識,
第8章 單元測驗和重構,討論單元測驗在任何所謂“可維護的代碼庫”中的重要性,本章回顧了單元測驗的重要性,并探究了單元測驗的主要框架(unittest和pytest),
第9章 常見的設計模式,回顧如何在Python中實作最常見的設計模式,不是從解決問題的角度,而是通過研究如何利用更好和更易于維護的解決方案來解決問題,本章提到了Python的一些特性,這些特性使得一些設計模式不可見,并采用實用的方法實作了其中的一些設計模式,
第10章 整潔架構,強調代碼整潔是實作良好架構的基礎,我們在第1章中提到的所有細節,以及在此程序中重溫的其他內容,在部署系統時都將在整個設計中發揮關鍵作用,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/257408.html
標籤:其他
上一篇:Markdown的使用
