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

PEP介紹

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

命名規(guī)則

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

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

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

類名(Class Names)

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

異常名 (Exception Names)

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

全局變量名(Global Variable Names)

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

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

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

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

函數(shù)名(Function Names)

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

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

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

補充:
python的類中,普通方法的第一個參數(shù)需要是self,它表示一個具體的實例本身;如果用了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)         #這里傳入實例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'>

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

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

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

謹記python特色的命名慣例

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

代碼布局

縮進(Indentation)

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

最大行寬(Maximum Line Length)

限制所有行的最大行寬為79字符。
折疊長行的首選方法是使用Python支持的圓括號、方括號(brackets)和花括號(braces)內(nèi)的行延續(xù)。如果需要,你可以在表達式周圍增加一對額外的圓括號,但是有時使用反斜杠看起來更好。確認恰當(dāng)?shù)乜s進了延續(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ù)中使用空行時,請謹慎的用于表示一個邏輯段落。


導(dǎo)入 (Imports)

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

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

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

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

  1. 標(biāo)準庫的導(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"


在表達式和語句中的空格(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]
  • 在賦值 (或其他) 運算符周圍的用于和其他語句對齊的一個以上的空格:
    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)識符(永遠不要修改標(biāo)識符的大小寫)。
如果注釋很短,可以省略末尾的句號。注釋塊通常由一個或多個段落組成,段落是由完整的句子構(gòu)成的,每個句子應(yīng)該以句號結(jié)尾。
你應(yīng)該在結(jié)束語句的句點(a sentence-ending period)后使用兩個空格。
非英語國家的Python程序員:請用英語書寫你的注釋,除非你120%的確信代碼永遠不會被不懂你的語言的人閱讀。

注釋塊(Block Comments)

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

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

節(jié)儉使用行內(nèi)注釋。
一個行內(nèi)注釋是和語句在同一行的注釋。行內(nèi)注釋應(yīng)該至少用兩個空格和語句分開。 它們應(yīng)該以一個 '#' 和單個空格開始。
行內(nèi)注釋不是必需的,事實上,如果說的是顯而易見事,還會使人分心。不要這樣做 :
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.itdecent.cn/users/2bd9b48f6ea8/latest_articles)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容