【python】python編碼規(guī)范

PEP介紹

PEP是 Python Enhancement Proposal 的縮寫,是Python增強(qiáng)建議書的意思。
Python的代碼風(fēng)格由PEP 8描述。這個文檔描述了Python編程風(fēng)格的方方面面。在遵守這個文檔的條件下,不同程序員編寫的Python代碼可以保持最大程度的相似風(fēng)格。這樣就易于閱讀,易于在程序員之間交流。

命名規(guī)則

不同的命名風(fēng)格

有許多不同的命名風(fēng)格。以下的有助于辨認(rèn)正在使用的命名風(fēng)格,這獨(dú)立于它們的作用。

  • 小寫串 (lowercase)
  • 帶下劃線的小寫串 (lower_case_with_underscores)
  • 大寫串 (UPPERCASE)
  • 帶下劃線的大寫串 (UPPER_CASE_WITH_UNDERSCORES)
  • 首字母大寫單詞串 (CapitalizedWords) (或 CapWords、CamelCase,因其字母看起來錯落有致,故得此名)
    注意: 在CapWords中使用縮寫,需要把縮寫的所有字母大寫。故HTTPServerError比HttpServerError更好。
  • 混合大小寫串 (mixedCase) (與首字母大寫串不同之處在于第一個字符是小寫的!)
  • 帶下劃線的首字母大寫串 (Capitalized_Words_With_Underscores) (丑陋!)

避免采用的名字

決不能使用字母'l'(L的小寫字母)、'O'(o的大寫字母)、'I'(i的大寫字母)) 作為單個字符的變量名。
在一些字體中,這些字符不能與數(shù)字1和0區(qū)別開。當(dāng)想要使用'l'時,用'L'代替它。

包和模塊名(Package and Module Names)

模塊名應(yīng)該是簡短的、全部小寫的名字??梢栽谀K名中使用下劃線以提高可讀性。Python包名也應(yīng)該是簡短的、全部小寫的名字,盡管不推薦使用下劃線。
因?yàn)槟K名被映射到文件名,有些文件系統(tǒng)大小寫不敏感并且截短長名字,所以把 模塊名選擇為相當(dāng)短就很重要了——這在Unix上不是問題,但當(dāng)把代碼遷移到Mac、Windows或DOS上時,就可能是個問題了。
當(dāng)一個用C或C++寫的擴(kuò)展模塊,有一個伴隨的Python模塊來提供一個更高層(例如,更面向?qū)ο?的接口時,C/C++ 模塊名有一個前導(dǎo)下劃線 (如:_socket)。

類名(Class Names)

幾乎沒有例外,類名使用首字母大寫單詞串(CapWords)的約定。內(nèi)部使用的類使用一個額外的前導(dǎo)下劃線。

異常名 (Exception Names)

因?yàn)楫惓?yīng)該是類,故類命名約定也適用于異常。然而,你應(yīng)該對異常名添加后綴"Error"(如果該異常的確是一個錯誤)。

全局變量名(Global Variable Names)

(我們希望這些變量只打算用于一個模塊內(nèi)部)。
對設(shè)計(jì)為通過"from M import "來使用的模塊,應(yīng)采用all機(jī)制來防止導(dǎo)出全局變量;或者使用舊的約定,為該類全局變量加一個前導(dǎo)下劃線(可能你想表明這些全局變量是只限制在該模塊內(nèi)部使用,"module non-public")。

補(bǔ)充:
在python的module中,可以使用 all 函數(shù)來定義這個module像其他引用自己的module導(dǎo)入的變量:

__all__ = ['bar', 'baz']
waz = 5
bar = 10

當(dāng)另一個模塊中使用import *聲明,waz和bar變量不會被導(dǎo)入,all可以隱藏不想被import的默認(rèn)值。

函數(shù)名(Function Names)

函數(shù)名應(yīng)該為小寫,必要時可用下劃線分隔單詞以增加可讀性。
混合大小寫 (mixedCase) 僅被允許用于這種風(fēng)格已經(jīng)占優(yōu)勢的上下文 (如: threading.py),以便保持向后兼容。

函數(shù)和方法的參數(shù)(Function and method arguments)

對實(shí)例的方法,總是用'self'做第一個參數(shù)。
對類的方法,總是用'cls'做第一個參數(shù)。
(如果函數(shù)的參數(shù)名與保留關(guān)鍵字沖突,在參數(shù)名后加一個下劃線,比用縮寫、錯誤的拼寫要好。因此"print_"比 "prnt"好。也許使用同義詞來避免沖突更好)

補(bǔ)充:
python的類中,普通方法的第一個參數(shù)需要是self,它表示一個具體的實(shí)例本身;如果用了staticmethod,那么就可以無視這個self,而將這個方法當(dāng)成一個普通的函數(shù)使用;而對于classmethod,它的第一個參數(shù)不是self,是cls,它表示這個類本身。

>>> class A(object):
        def foo1(self):
            print "Hello",self
        @staticmethod
        def foo2():
            print "hello"
        @classmethod
        def foo3(cls):
            print "hello",cls

>>> a = A()
>>> a.foo1()          #最常見的調(diào)用方式,但與下面的方式相同
Hello <__main__.A object at 0x9f6abec>
>>> A.foo1(a)         #這里傳入實(shí)例a,相當(dāng)于普通方法的self
Hello <__main__.A object at 0x9f6abec>
>>> A.foo2()          #這里,由于靜態(tài)方法沒有參數(shù),故可以不傳東西
hello
>>> A.foo3()          #這里,由于是類方法,因此,它的第一個參數(shù)為類本身。
hello <class '__main__.A'>
>>> A                 #可以看到,直接輸入A,與上面那種調(diào)用返回同樣的信息。
<class '__main__.A'>

方法名和實(shí)例變量(Method Names and Instance Variables)

采用函數(shù)命名規(guī)則:小寫單詞,必要時可用下劃線分隔單詞以增加可讀性。
僅對 non-public 方法和實(shí)例變量采用一個前導(dǎo)下劃線。

為避免與子類命名沖突,采用兩個前導(dǎo)下劃線來觸發(fā) Python 的命名重整規(guī)則。
Python用類名重整這些名字:如果類Foo有一個屬性名為__a,它不能以Foo.__a訪問(執(zhí)著的用戶還是可以通過Foo._Foo__a得到訪問權(quán))。通常,雙 前導(dǎo)下劃線僅被用來避免與基類的屬性發(fā)生名字沖突。

謹(jǐn)記python特色的命名慣例

  • 公開屬性應(yīng)該沒有前導(dǎo)下劃線
  • 如果公開屬性名和保留關(guān)鍵字沖突,在你的屬性名后添加一個后置下劃線
  • 對簡單的公開數(shù)據(jù)屬性 (data attribute),最好只暴露屬性名,沒有復(fù)雜的訪問/修改方法
    謹(jǐn)記Python為將來增強(qiáng)提供了一條容易的途徑,你應(yīng)該發(fā)現(xiàn)簡單數(shù)據(jù)屬性需要增加功能行為。在那種情況,用特性(properties)把功能實(shí)現(xiàn)隱藏在簡單數(shù)據(jù)屬性訪問語法后面。
  • 以單一下劃線的變量名(_X)不會被from module import *語句導(dǎo)入。一個前導(dǎo)下劃線的函數(shù)是私有函數(shù)。
    Python 中不存在私有變量一說,若是遇到需要保護(hù)的變量,使用小寫和一個前導(dǎo)下劃線。但這只是程序員之間的一個約定,用于警告說明這是一個私有變量,外部類不要去訪問它。但實(shí)際上,外部類還是可以訪問到這個變量。
  • 前后有兩個下劃線的變量名(X)是系統(tǒng)定義的變量名,對解釋器有特殊意義。包括兩個前導(dǎo)下劃線,兩個后置下劃線的函數(shù)名,這種風(fēng)格只應(yīng)用于特殊函數(shù),比如操作符重載等。
  • 以兩個下劃線開頭,但結(jié)尾沒有兩個下劃線的變量名(__X)是類的本地變量

代碼布局

縮進(jìn)(Indentation)

每級縮進(jìn)用 4 個空格。
絕不要混合使用 tab 和空格。
最流行的 Python 縮進(jìn)方式是僅使用空格,其次是僅使用制表符?;旌现票矸涂?格縮進(jìn)的代碼將被轉(zhuǎn)換成僅使用空格。調(diào)用 Python 命令行解釋器時使用 -t 選項(xiàng), 可對代碼中不合法的混用制表符和空格發(fā)出警告 (warnings)。使用 -tt 時警告將變 成錯誤。這些選項(xiàng)是被高度推薦的。
對新項(xiàng)目,強(qiáng)烈推薦只用空格,而不是用tabs。大多數(shù)編輯器擁有使之易于實(shí)現(xiàn)的功能。

最大行寬(Maximum Line Length)

限制所有行的最大行寬為79字符。
折疊長行的首選方法是使用Python支持的圓括號、方括號(brackets)和花括號(braces)內(nèi)的行延續(xù)。如果需要,你可以在表達(dá)式周圍增加一對額外的圓括號,但是有時使用反斜杠看起來更好。確認(rèn)恰當(dāng)?shù)乜s進(jìn)了延續(xù)的行。

class Rectangle(Blob): 
    def __init__(self, width, height,  
        color='black', emphasis=None, highlight=0): 
        if width == 0 and height == 0 and \  
            color == 'red' and emphasis == 'strong' or \ highlight > 100:  
            raise ValueError("sorry, you lose")  
        if width == 0 and height == 0 and (color == 'red' or  
                emphasis is None): 
            raise ValueError("I don't think so")  
        Blob.__init__(self, width, height,  
                    color, emphasis, highlight) 

空行(Blank Lines)

用兩行空行分割頂層函數(shù)和類的定義。
類內(nèi)方法的定義用單個空行分割。
在函數(shù)中使用空行時,請謹(jǐn)慎的用于表示一個邏輯段落。


導(dǎo)入 (Imports)

  • 通常應(yīng)該在單獨(dú)的行中導(dǎo)入:
    Yes: import os
    import sys

No: import sys, os
但是這樣也是可以的:
from subprocess import Popen, PIPE

  • Imports通常被放置在文件的頂部,僅在模塊注釋和文檔字符串之后,在模塊的全局變量和常量之前。

  • Imports應(yīng)該按照如下順序成組安放:

  1. 標(biāo)準(zhǔn)庫的導(dǎo)入
  2. 相關(guān)的第三方包的導(dǎo)入
  3. 本地應(yīng)用/庫的特定導(dǎo)入
  • 對于內(nèi)部包的導(dǎo)入是非常不推薦使用相對導(dǎo)入的。對所有導(dǎo)入總是使用包的絕對路徑

  • 從一個包含類的模塊中導(dǎo)入類時,通??梢詫懗蛇@樣:
    from myclass import MyClass
    from foo.bar.yourclass import YourClass
    如果這樣寫導(dǎo)致了本地名字沖突,那么就這樣寫:
    import myclass
    import foo.bar.yourclass
    并使用"myclass.MyClass" and "foo.bar.yourclass.YourClass"


在表達(dá)式和語句中的空格(Whitespace in Expressions and Statements)

  • 緊挨著圓括號、方括號和花括號:
    Yes: spam(ham[1], {eggs: 2})
    No: spam( ham[ 1 ], { eggs: 2 } )
  • 緊貼在逗號、分號或冒號前:
    Yes: if x == 4: print x, y; x, y = y, x
    No: if x == 4 : print x , y ; x , y = y , x
  • 緊貼著函數(shù)調(diào)用的參數(shù)列表前的開式括號:
    Yes: spam(1)
    No: spam (1)
  • 緊貼在索引或切片 (indexing or slicing) 開始的開式括號前:
    Yes: dct['key'] = lst[index]
    No: dct ['key'] = lst [index]
  • 在賦值 (或其他) 運(yùn)算符周圍的用于和其他語句對齊的一個以上的空格:
    Yes:
    x = 1
    y = 2
    long_variable = 3
    No:
    x = 1
    y = 2
    long_variable = 3

注釋(Comments)

同代碼不一致的注釋比沒注釋更差。當(dāng)代碼修改時,始終優(yōu)先更新注釋!
注釋應(yīng)該是完整的句子。如果注釋是一個短語或句子,首字母應(yīng)該大寫,除非它是一個以小寫字母開頭的標(biāo)識符(永遠(yuǎn)不要修改標(biāo)識符的大小寫)。
如果注釋很短,可以省略末尾的句號。注釋塊通常由一個或多個段落組成,段落是由完整的句子構(gòu)成的,每個句子應(yīng)該以句號結(jié)尾。
你應(yīng)該在結(jié)束語句的句點(diǎn)(a sentence-ending period)后使用兩個空格。
非英語國家的Python程序員:請用英語書寫你的注釋,除非你120%的確信代碼永遠(yuǎn)不會被不懂你的語言的人閱讀。

注釋塊(Block Comments)

注釋塊通常應(yīng)用于跟隨其后的一些 (或者全部) 代碼,并和這些代碼有著相同的縮進(jìn) 層次。注釋塊中每行以 '#' 和一個空格開始 (除非它是注釋內(nèi)的縮進(jìn)文本)。
注釋塊內(nèi)的段落以僅含單個 '#' 的行分割。

行內(nèi)注釋(Inline Comments)

節(jié)儉使用行內(nèi)注釋。
一個行內(nèi)注釋是和語句在同一行的注釋。行內(nèi)注釋應(yīng)該至少用兩個空格和語句分開。 它們應(yīng)該以一個 '#' 和單個空格開始。
行內(nèi)注釋不是必需的,事實(shí)上,如果說的是顯而易見事,還會使人分心。不要這樣做 :
x = x + 1 # Increment x
但是有時,這樣是有益的:
x = x + 1 # Compensate for border

參考資料

如何使用Pylint來規(guī)范Python代碼風(fēng)格
PEP 8 - Style Guide for Python Code

轉(zhuǎn)載請注明作者Jason Ding及其出處
Github博客主頁(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.lxweimin.com/users/2bd9b48f6ea8/latest_articles)

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

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

  • --< > 令人討厭的小人物身上有著愚蠢的一致性 --(A Foolish Consistency is the ...
    LittleWizard閱讀 3,254評論 0 4
  • 更新時間:2016/5/13 介紹 本文檔所提供的編碼規(guī)范,適用于主要的Python發(fā)行版中組成標(biāo)準(zhǔn)庫的Pytho...
    超net閱讀 5,883評論 0 15
  • Python編碼規(guī)范 1 排版 1.1 Indentation縮進(jìn) 在參數(shù)過多時適當(dāng)縮進(jìn) 換行應(yīng)該使用同級的縮進(jìn)...
    帝Bug閱讀 848評論 0 1
  • Python是一種對代碼風(fēng)格很重視的語言,從縮進(jìn)就能看出這一點(diǎn),Python強(qiáng)調(diào)易于理解。最近在負(fù)責(zé)代碼重構(gòu)的工作...
    知曰閱讀 10,969評論 1 85
  • 一 李翠娥拿著智能手機(jī),有些不相信她三姨的話。她三姨臨回家時千叮嚀萬囑咐,讓她在屏幕上千萬...
    Mr_稻香老農(nóng)閱讀 513評論 32 32