python代碼風格指南:pep8 中文版
本文檔所提供的編碼規範,適用於主要的Python發行版中組成標準庫的Python代碼。請參閱PEP關於Python的C實現的C編碼風格指南的描述。
本文檔和PEP257(文檔字符串規範)改編自Guido的《Python Style Guide》一文,並從《Barry‘s style guide》添加了部分內容作為補充。
這篇風格指南隨著時間的推移而逐漸演變,隨著語言本身的變化,一些過去的約定已經過時,並確定了更多新的約定。
許多項目都有自己的編碼風格指南。如果有任何沖突,優先使用該項目特定的指南。
愚蠢地堅持一致性是無知的妖怪
Guido的一個重要的見解是,代碼閱讀的次數比編寫的次數多。這裏提供的指南旨在提高代碼的可讀性,並使各種不同的Python代碼一致。如PEP20所說,“可讀性很重要”。
風格指南是關於一致性的。與本風格指南一致很重要。項目中的一致性更重要。一個模塊或函數中的一致性最重要。
最重要的是:知道何時會不一致——有時風格指南就不適用了。懷疑時,作出你最佳的判斷。看看其他的例子,並決定什麽是最好的。不要猶豫,盡管發問!
特別地:不要只為遵從這個PEP而打破向後兼容性!
可以忽略部分風格指南的好理由,不要只為遵從這個PEP而打破向後兼容性!
忽視既定指南的一些其他的好理由:
- 當應用指南會降低代碼的可讀性,即使對於那些習慣遵照這個PEP來閱讀代碼的人來說。
- 與周圍的代碼保持一致也會破壞它(可能是歷史原因)——雖然這也是收拾別人爛攤子的好機會(在真正的XP風格中)。
- 因為問題代碼先於指南,又沒有其它的修改理由。
- 代碼需要兼容老版本,本風格指南不建議使用的Python特性。
代碼布局
縮進
每級縮進用4個空格。
括號中使用垂直隱式縮進或使用懸掛縮進。當使用懸掛縮進時,應考慮以下內容:第一行上沒有參數,後續行要有縮進。
·Yes:
# 與起始定界符對齊: foo = long_function_name(var_one, var_two, var_three, var_four) # 使用更多的縮進,以區別於其他代碼 def long_function_name( var_one, var_two, var_three, var_four): print(var_one) # 懸掛縮進,必須增加一層縮進 foo = long_function_name( var_one, var_two, var_three, var_four)
No:
# 不使用垂直參數時,第一行不能有參數。 foo = long_function_name(var_one, var_two, var_three, var_four) # 參數的縮進與print()函數縮進相同。 def long_function_name( var_one, var_two, var_three, var_four): print(var_one)
對於連續的行而言,四個空格的規定不是必須的。
#懸掛縮進不一定是4個空格。 # Hanging indents *may* be indented to other than 4 spaces. foo = long_function_name( var_one, var_two, var_three, var_four)
if 語句跨行時,兩個字符關鍵字加上一個空格,再加上左括號構成了很好的縮進。後續行暫時沒有規定,以下有三種格式,建議用三種:
# No extra indentation.沒有額外的縮進 if (this_is_one_thing and that_is_another_thing): do_something() # Add a comment, which will provide some distinction in editors.添加註釋 # supporting syntax highlighting. if (this_is_one_thing and that_is_another_thing): # Since both conditions are true, we can frobnicate. do_something() # Add some extra indentation on the conditional continuation line. #額外添加縮進,推薦 if (this_is_one_thing and that_is_another_thing): do_something()
也請參閱下面的二進制操作符之前或之後是否要中斷的討論。
右邊括號也可以另起一行。有兩種格式,建議第2種。
# 右括號不回退,個人不推薦 my_list = [ 1, 2, 3, 4, 5, 6, ] result = some_function_that_takes_arguments( ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ) # 右括號回退 my_list = [ 1, 2, 3, 4, 5, 6, ] result = some_function_that_takes_arguments( ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, )
空格或Tab?
-
空格是首選的縮進方法。
-
Tab僅僅在已經使用tab縮進的代碼中為了保持一致性而使用。
-
Python 3中不允許混合使用Tab和空格縮進。
-
Python 2的包含空格與Tab和空格縮進的應該全部轉為空格縮進。
Python2命令行解釋器使用-t選項時有非法混合Tab和空格的情況會告警。當使用-tt警告提升為錯誤。強烈推薦這些選項!另外個人推薦pep8和autopep8模塊。
最大行寬
限制所有行的最大行寬為79字符。
文本長塊,比如文檔字符串或註釋,行長度應限制為72個字符。
多數工具默認的續行功能會破壞代碼結構,使它更難理解,不推薦使用。但是超過80個字符加以提醒是必要的。一些工具可能根本不具備動態換行功能。
一些團隊強烈希望更長的行寬。如果能達成一致,可以從從80提高到100個字符(最多99個字符)增加了標稱線的長度,不過依舊建議文檔字符串和註釋保持在72的長度。
Python標準庫比較保守,限制行寬79個字符(文檔字符串/註釋72)。
續行的首選方法是使用小括號、中括號和大括號反斜線仍可能在適當的時候。其次是反斜杠。比如with語句中:
with open(‘/path/to/some/file/you/want/to/read‘) as file_1, open(‘/path/to/some/file/being/written‘, ‘w‘) as file_2: file_2.write(file_1.read())
類似的還有assert。
應該在二進制操作符之前或之後續行嗎?
幾十年來,推薦的樣式是在二進制運算符之後中斷。但這可能會以兩種方式損害可讀性:操作員傾向於分散在屏幕上的不同列上,並且每個運算符從其操作數移動到上一行。在這裏,眼睛必須做額外的工作,告訴哪些項目被添加,哪些被減去。
# No: operators sit far away from their operands.操作員坐在遠離操作數的地方 income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest)
為了解決這個可讀性問題,數學家和他們的出版商遵循相反的慣例。Donald Knuth解釋了他的計算機和排版系列中的傳統規則:“雖然一個段落中的公式總是在二進制操作和關系之後斷裂,但顯示公式總是在二進制操作之前中斷。”
遵循數學傳統,通常會產生更多可讀代碼。
# Yes: easy to match operators with operands.易於與操作數匹配的運算符 income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest)
在Python代碼中,允許在二進制操作符之前或之後中斷,只要約定在本地是一致的。對於新代碼,Knuth的風格被提出。
空行
-
兩行空行分割頂層函數和類的定義。
-
類的方法定義用單個空行分割。
-
額外的空行可以必要的時候用於分割不同的函數組,但是要盡量節約使用。
-
額外的空行可以必要的時候在函數中用於分割不同的邏輯塊,但是要盡量節約使用。
-
Python接 contol-L作為空白符;許多工具視它為分頁符,這些要因編輯器而異。
源文件編碼
在核心Python發布的代碼應該總是使用UTF-8(ASCII在Python 2)。
ASCII文件(Python 2)或UTF-8(Python 3)不應有編碼聲明。
標準庫中非默認的編碼應僅用於測試或當註釋或文檔字符串,比如包含非ASCII字符的作者姓名,盡量使用\x , \u , \U , or \N。
Python 3.0及以後版本,PEP 3131可供參考,部分內容如下:在Python標準庫必須使用ASCII標識符,並盡量只使用英文字母。此外字符串和註釋也必須用ASCII。唯一的例外是:(a)測試非ASCII的功能,和(b)作者的名字不是拉丁字母。
導入
-
導入在單獨行
Yes: import os import sys No: import sys, os
這樣說也可以
from subprocess import Popen, PIPE
-
導入始終在文件的頂部,在模塊註釋和文檔字符串之後,在模塊全局變量和常量之前。
導入順序如下:標準庫進口,相關的第三方庫,本地庫。各組的導入之間要有空行。
相關的all放在導入之後。
-
推薦絕對路徑導入,因為它們通常更可讀,而且往往是表現更好的(或至少提供更好的錯誤消息。
import mypkg.sibling from mypkg import sibling from mypkg.sibling import example
在絕對路徑比較長的情況下,也可以使用相對路徑:
from . import sibling from .sibling import example
標準庫代碼應該避免復雜的包布局,並且總是使用絕對的導入。
在Python 3中不應該使用和刪除隱式相對導入。
導入類的方法:
from myclass import MyClass from foo.bar.yourclass import YourClass
如果和本地名字有沖突:
import myclass import foo.bar.yourclass
禁止使用通配符導入。
通配符導入(from <module> import *)應該避免,因為它不清楚命名空間有哪些名稱存,混淆讀者和許多自動化的工具。唯一的例外是重新發布對外的API時可以考慮使用。
字符串引用
Python中單引號字符串和雙引號字符串都是相同的。註意盡量避免在字符串中的反斜杠以提高可讀性。
根據PEP 257, 三個引號都使用雙引號。
表達式和語句中的空格
強制要求
括號裏邊避免空格
# 括號裏邊避免空格 # Yes spam(ham[1], {eggs: 2}) # No spam( ham[ 1 ], { eggs: 2 } )
在尾逗號和後面的括號之間。
Yes: foo = (0,) No: bar = (0, )
逗號,冒號,分號之前避免空格
# 逗號,冒號,分號之前避免空格 # Yes if x == 4: print x, y; x, y = y, x # No if x == 4 : print x , y ; x , y = y , x
索引操作中的冒號當作操作符處理前後要有同樣的空格(一個空格或者沒有空格,個人建議是沒有。
Yes: ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:] ham[lower:upper], ham[lower:upper:], ham[lower::step] ham[lower+offset : upper+offset] ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)] ham[lower + offset : upper + offset] No: ham[lower + offset:upper + offset] ham[1: 9], ham[1 :9], ham[1:9 :3] ham[lower : : upper] ham[ : upper]
函數調用的左括號之前不能有空格
# Yes spam(1) dct[‘key‘] = lst[index] # No spam (1) dct [‘key‘] = lst [index]
賦值等操作符前後不能因為對齊而添加多個空格
# Yes x = 1 y = 2 long_variable = 3 # No x = 1 y = 2 long_variable = 3
其他建議
python代碼風格指南:pep8 中文版