Python 代碼風格,python代碼風格

來源:互聯網
上載者:User

Python 代碼風格,python代碼風格

1 原則

在開始討論Python社區所採用的具體標準或是由其他人推薦的建議之前,考慮一些總體原則非常重要。

請記住可讀性標準的目標是提升可讀性。這些規則存在的目的就是為了協助人讀寫代碼,而不是相反。

本小節討論你所需記住的一些原則。

1.1 假定你的代碼需要維護

人們很容易傾向相信某時所完成的工作在未來不需要添加一部分或對其維護。這是由於很難預料到未來的需求,以及低估自己造成Bug的傾向。然而,所寫代碼很少不被修改一直存在。

如果你假設自己所寫代碼會“一勞永逸”的無需之後進行閱讀、調試或修補,那麼你就會非常容易陷入忽視其他可讀性原則的境地,這僅僅是因為你相信“這次並不重要”。

因此,保持對自己感覺所寫代碼無需維護的直覺的不信任才是上策。穩賺不賠的辦法是賭自己將會再次見到自己寫的代碼。即使你不維護,那也需要其他人維護。

1.2 保持一致性

一致性的兩個方面分別為:內部一致性和外部一致性。

無論是從代碼風格和代碼結構層面來講,代碼都要盡量滿足內部一致性。無論是哪種格式化規則,代碼風格都要貫穿項目保持一致。代碼結構的一致性也就是同樣類型的代碼放到一起。這樣項目容易把控。

代 碼還應該保持外部一致性。項目與代碼的結構與其他人保持一致,如果一個新來的開發人員開啟你的項目,你不應該讓他的反應是:“我從來沒見過像這樣的東 西”。社區指導原則很重要,因為這就是開發人員加入到你的項目預期所見。類似的,以及相同的原因,請認真看待在使用特定架構時完成任務以及組織代碼所採用 的標準。

1.3 考慮事物存在方式,尤其是帶有資料

存在論(Ontology)的主要意思就是“關於存在的研究”。在哲學上(在該領域這個詞很常用)存在論是關於現實與存在本質的研究,是形而上學的子集。

而對於寫軟體程式來說,存在論指的是關注不同“事物”在程式中如何存在。你如何將概念轉化為在資料庫中表示?亦或是用類結構表示?

這類問題最終影響你編寫或組織代碼的方式。是否使用繼承或是組合來組織兩個類之間的關係?資料庫中用哪個表完成這項功能或是這個列屬於誰?

這些建議最終歸結為“在寫代碼之前先思考”。尤其是思考程式希望實現的目標,以及程式之間如何互動。程式是一個對象與資料互動的世界。那麼,它們之間協作所需遵循的規則是什嗎?

1.4 不要做重複工作

當編寫代碼時,請考慮隨著時間重複使用的值將會變更的情況。該值是否被用於多個模組或函數中?如果必要,需要花費多大代價修改它?

同樣的原則適用於函數。你是否在程式中有大量的重複的代碼?如果這些重複程式碼數較多,可以考慮將其抽象到一個函數中,如果出現修改代碼的需求,則更容易管理。

另一方面,對於該原則不要過猶不及。並不是所有值都需要在模組中定義為常量(這麼做會損害可讀性和可維護性)。請明智判斷,不斷問這樣一個問題:“如果需要變更該代碼,變更該代碼的所有位置所需要的成本是多少”?

1.5 讓注釋講故事

代碼是一個故事。它是所發生故事的說明,在使用者與程式互動過程中,從開始到結束。程式從某一點開始(可能帶有一些輸入),沿著一系列“選擇自己的冒險故事”步驟到達終點,並結束(很可能帶有一些輸出結果)。

採用的注釋風格可以是每一些行代碼之前就添加一段注釋,用於解釋代碼的功能。如果代碼是一個故事,那麼注釋就是故事的解釋與旁白。

如果敘事式注釋做的很好,讀者就可以通過閱讀注釋瞭解故事,從而解析代碼(例如,當嘗試解決問題或維護代碼時),然後可以從零開始快速瞭解所需維護的代碼,這樣就可以專註於代碼本身所代表的意義。

敘事式注釋還可以協助解釋代碼意圖。它可以回答這樣的問題:“寫這段代碼的人希望完成的目標是什嗎?”偶爾,還可以協助回答問題:“為什麼以這種方式完成工作”?這些問題是在你閱讀代碼時很自然會問的,為這些問題提供答案將會協助瞭解這些內容。

因此,注釋用於解釋代碼中不顯而易見或複雜部分的原理。如果使用了有點複雜的演算法,請考慮將指向解釋模式文章的連結以及其他使用樣本加入注釋。

1.6 奧卡姆剃刀原則

編 寫可維護代碼最重要的原則通俗來講就是奧卡姆剃刀原則:最簡單的解決方案通常是最好的。在他的“Python之禪”博文 (https://www.python.org/dev/peps/pep-0020/),該頁面是編程格言的集合(例如,在Python控制台中輸入 “import this”就可以看到這篇),Tim Peters也包括了類似下面這句“如果你無法向人描述你的方案,那肯定不是一個好方案”。

上述原則在代碼如何運行與代碼外觀層面都生效。當提到代碼運行時,簡單的系統更加容易維護。實現的簡單化意味著更少引入複雜的BUG,哪些維護你代碼的人(包括你自己)更容易憑直覺理解代碼所代表的含義,並在不踩坑的前提下為程式增加代碼。

至 於代碼的外觀,請記住,儘可能使得閱讀代碼就好像是在瞭解代碼所做工作的故事,而不是為瞭解析詞彙。詞彙是手段,而故事才是最終目的。寫一條諸如“不要使 用三元運算子”很容易。然而僅僅是遵循這些規則(雖然有價值)並不是代碼明晰的充分條件。請專註以儘可能簡潔的方式編寫和組織代碼

2 標準

Python社區大部分遵循所謂的PEP 8(https://www.python.org/
dev/peps/pep-0008/)指導原則,由Guido van Rossum(Python之父)編寫並被包括Python標準庫中的大多數主流Python項目採用。

PEP 8的普遍性是其強大的原因之一。該標準被大多數社區項目採納,因此你可以預計大多數你遇到的Python代碼都遵循該標準。當你以這種方式編寫代碼時,代碼會更加容易閱讀,也更容易編寫。

2.1 簡潔的規則

大多數PEP 8中的指導原則都很簡單明了。部分重點如下:

l 使用4個空格縮排。不要使用定位字元(\t)。

l 變數應該使用底線串連,不使用駱駝式命名風格(使用my_var而不是myVar)。類名稱以字母開頭就是駱駝式命名風格(例如:MyClass)。

l 如果一個變數的用處是:“僅內部使用”,在變數名稱之前加上底線。

l 在運算子前後加上單空格(例如,x + y,不是x+y),也包含賦值運算子(z = 3而不是z=3),只有在關鍵字參數情況下不適用,在這種情況下,空格可以省略。

l 在列表和字典中省略不必要的括弧,(例如: [1, 1, 2, 3, 5],而不是[ 1, 1, 2, 3, 5 ])。
請閱讀Python代碼風格指南獲得更多樣本以及有關這些規則的更多討論。

2.2 文檔字串

請記住,在Python中,如果在一個函數或類中第一個語句是一個字串,該字串會自動賦值給一個特殊的“_doc_”變數,該變數在調用Help(和一些其他的類)時會被使用。

PEP 8 規定文檔字串(該名稱可以被望文生義)是必須的。

"""Do X, Y, andZ, then return the result."""

該句子與作為描述的文檔字串的對比:

"""Does X, Y, andZ, then returns the result."""

如果文檔字串是一行,那麼需要在類或函數體之前加空行。如果文檔字串有多行,則將結束的雙引號單獨放一行。

2.3 空行

空行用於邏輯分塊。

PEP8規定“最進階”的類和函數定義之間有兩個空行。

class A(object):passclass B(object):pass

代碼清單1.

PEP 8還規定除了最進階之外,類和函數的定義以一個空行分隔。

class C(object):def foo(self):passdef bar(self):pass 

代碼清單2.

在函數或其他程式碼片段中使用單空行分隔邏輯段是合理的。請考慮在邏輯段之前使用注釋解釋程式碼片段的作用。

2.4 匯入

Python允許絕對路徑匯入和相對路徑匯入。在Python2中,解譯器會嘗試相對匯入,如果找不到路徑,然後再嘗試使用絕對匯入。

在Python 3中,使用特殊文法標記相對當如----以(.)開頭----“正常”的匯入方式只會嘗試相對路徑。Python 3的文法在Python 2.6以後版本可以使用。除此之外你可以使用—“_future_”關閉隱式相對路徑匯入。

如果可能,盡量使用絕對路徑匯入。如果不得不使用相對路徑,請使用顯式匯入風格。如果你為Python 2.6或 2.7編寫代碼,請考慮選擇Python 3中的顯式風格。

當匯入模組時,每個模組單獨佔一行。

import osimport sys

代碼清單3

然而,如果你從同一個模組中匯入多個名稱,當然可以將這些名稱分組到一行中。

from datetime import date, datetime, timedelta

 

代碼清單4

除此之外,雖然PEP 8並沒有強制要求,考慮以包來源的方式將匯入分組。對於每一組,按照字母表順序排序。

另外,在匯入時,請不要忘了使用as關鍵字給匯入的內容起別名。

from foo.bar import really_long_name as name

代碼清單5

這使得你可以簡化被頻繁使用的長名稱或不規範命名的名稱。

當匯入被頻繁使用且原始名稱無論何種原因不規範時,別名就很有價值了。

另一方面,請記住當你這麼做時,你會在你的模組中掩蓋了原始名稱,如果沒必要使用別名,這會使得代碼變得不清晰。無論是使用何種工具,要做到具體情況,具體分析。

2.5 變數

正如之前所提到的,變數名稱使用底線串連,而不要使用駱駝代碼風格(例如,my_val而不是myVal)。除此之外,起一個具有描述性的名稱同樣重要。

通常情況下使用非常短的變數名稱並不合適,雖然某些情況下這麼做也能接受,比如在迴圈中的變數(例如,for k in mydict_item())。

避免命名的函數名稱與Python語言中的常用名稱重複,就算是解譯器允許也不行。無論在任何情況下,都不要命名某個對象為sum或print。類似的,避免list或dict之類的名稱。

如 果你必須要命名一個與Python類型與關鍵字同名的變數,慣例是在變數名稱之後加底線;相比修改名稱的拼字來說,這麼做更加可取。例如,如果你將一個 類作為參數傳遞給一個函數,那麼參數名稱應該為class_,而不是klass(一個例外是靜態方法,按照慣例使用cls作為第一個參數)。

2.6 注釋

注釋應該使用英語寫完整的句子(譯者註:當然在國內這點值得商榷),放在相關的代碼之前。正確使用首字母大寫和文法,以及保證拼字正確。

同時,保證注釋最新。如果代碼變更,那麼注釋可能也需要隨之變更。你應該不希望注釋與代碼錶示的意思相反,這很容易導致混淆。

模組可能包含一個注釋頭,通常由版本控制系統產生,其中包含檔案版本的資訊。這使得發現檔案被修改變得容易,尤其是在將模組分發給別人使用時。

2.7 行長度

Python代碼風格最有爭議(也是最常被拒絕使用的)的方面是對行長度的限制。PEP 8要求行長度不超過79個字元,文檔字串不超過72個字元。

該規則讓很多開發人員感到沮喪,這些開發人員認為我們生活在一個27寸寬屏顯示器的時代。GitHub是一個非常流行共用代碼的網站,所使用的視窗寬度是120個字元。

而該規則的支援者指出很多人依然使用窄屏或80字元長度的終端,甚至僅僅是將代碼視窗的寬度設定為小於螢幕寬度。

爭論很難有一個結果。總之,無論是遵循79字元寬度的標準或是更寬的標準,你應該按照項目標準的規範編碼。當行長度過長時,你應該知道如何處理代碼。

使用圓括弧是封裝單行長代碼的最佳方式,如下所示:

if (really_long_identifier_that_maybe_should_be_shorter andother_really_long_identifier_that_maybe_should_be_shorter):do_something()

 

代碼清單6

只要可能,使用該方法,而不是在分行符號之前使用 \字元。注意在使用諸如and之類的操作符時,儘可能將其置於分行符號之前。

封裝函數調用也是可以的。PEP 8列出了許多可接受的方式完成封裝。一般規則是使得同層級行縮排保持一致。

really_long_function_name(categories=[x.y.COMMON_PHRASES,x.y.FONT_PREVIEW_PHRASES,],phrase='The quick brown fox jumped over the lazy dogs.',)

 

代碼清單7

當在函數調用、列表或字典中分行時,在行結尾部分添加逗號。

3 小結

大多數時候,一年後閱讀你代碼的人就是你自己。記憶並不像一開始時那麼好用。在編寫代碼時沒有留心代碼的可讀性與可維護性自然會使得代碼難以閱讀和維護。

通觀本書,你學會了如何使用Python中多種模組、類與結構。當需要決定如何解決問題時,請記住調試代碼比寫代碼更有技術含量。

因此,以代碼儘可能簡潔和可讀為目標。一年後的你將會感謝自己。當然,你的同事以及下屬也會感謝你。

------本篇結選自本人翻譯的書《Python 進階編程》, 清華大學出版社-------------------------------------------------------------------------------------------------

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.