python入門之編碼風(fēng)格規(guī)范分享:
本項目并非 Google 官方項目, 而是由國內(nèi)程序員憑熱情創(chuàng)建和維護。
如果你關(guān)注的是 Google 官方英文版, 請移步?Google Style Guide
以下代碼中?Yes?表示推薦,No?表示不推薦。
分號
不要在行尾加分號, 也不要用分號將兩條命令放在同一行。
行長度
每行不超過80個字符
以下情況除外:
長的導(dǎo)入模塊語句
注釋里的URL
不要使用反斜杠連接行。
Python會將?圓括號, 中括號和花括號中的行隱式的連接起來?, 你可以利用這個特點. 如果需要, 你可以在表達式外圍增加一對額外的圓括號。
推薦:foo_bar(self,width,height,color='black',design=None,x='foo',emphasis=None,highlight=0)if(width==0andheight==0andcolor=='red'andemphasis=='strong'):
如果一個文本字符串在一行放不下, 可以使用圓括號來實現(xiàn)隱式行連接:
x=('這是一個非常長非常長非常長非常長 ''非常長非常長非常長非常長非常長非常長的字符串')
在注釋中,如果必要,將長的URL放在一行上。
Yes:# See details at#No:# See details at# \# v2.0/csv_file_name_extension_full_specification.html
注意上面例子中的元素縮進; 你可以在本文的 :ref:`縮進`部分找到解釋.
括號
寧缺毋濫的使用括號
除非是用于實現(xiàn)行連接, 否則不要在返回語句或條件語句中使用括號. 不過在元組兩邊使用括號是可以的.
Yes:iffoo:bar()whilex:x=bar()ifxandy:bar()ifnotx:bar()returnfoofor(x,y)indict.items():...No:if(x):bar()ifnot(x):bar()return(foo)縮進
用4個空格來縮進代碼
絕對不要用tab, 也不要tab和空格混用. 對于行連接的情況, 你應(yīng)該要么垂直對齊換行的元素(見 :ref:`行長度` 部分的示例), 或者使用4空格的懸掛式縮進(這時第一行不應(yīng)該有參數(shù)):
Yes:# 與起始變量對齊foo=long_function_name(var_one,var_two,var_three,var_four)# 字典中與起始值對齊foo={long_dictionary_key:value1+value2,...}# 4 個空格縮進,第一行不需要foo=long_function_name(var_one,var_two,var_three,var_four)# 字典中 4 個空格縮進foo={long_dictionary_key:long_dictionary_value,...}No:# 第一行有空格是禁止的foo=long_function_name(var_one,var_two,var_three,var_four)# 2 個空格是禁止的foo=long_function_name(var_one,var_two,var_three,var_four)# 字典中沒有處理縮進foo={long_dictionary_key:long_dictionary_value,...}空行
頂級定義之間空兩行, 方法定義之間空一行
頂級定義之間空兩行, 比如函數(shù)或者類定義. 方法定義, 類定義與第一個方法之間, 都應(yīng)該空一行. 函數(shù)或方法中, 某些地方要是你覺得合適, 就空一行.
空格
按照標準的排版規(guī)范來使用標點兩邊的空格
括號內(nèi)不要有空格.
按照標準的排版規(guī)范來使用標點兩邊的空格
Yes:spam(ham[1],{eggs:2},[])No:spam(ham[1],{eggs:2},[])
不要在逗號, 分號, 冒號前面加空格, 但應(yīng)該在它們后面加(除了在行尾).
Yes:ifx==4:printx,y x,y=y,xNo:ifx==4:printx,y x,y=y,x
參數(shù)列表, 索引或切片的左括號前不應(yīng)加空格.
Yes:spam(1)no:spam(1)Yes:dict['key']=list[index]No:dict['key']=list[index]
在二元操作符兩邊都加上一個空格, 比如賦值(=), 比較(==, <, >, !=, <>, <=, >=, in, not in, is, is not), 布爾(and, or, not). 至于算術(shù)操作符兩邊的空格該如何使用, 需要你自己好好判斷. 不過兩側(cè)務(wù)必要保持一致.
Yes:x==1No:x<1
當'='用于指示關(guān)鍵字參數(shù)或默認參數(shù)值時, 不要在其兩側(cè)使用空格.
Yes:defcomplex(real,imag=0.0):returnmagic(r=real,i=imag)No:defcomplex(real,imag=0.0):returnmagic(r=real,i=imag)
不要用空格來垂直對齊多行間的標記, 因為這會成為維護的負擔(dān)(適用于:, #, =等):
Yes:foo=1000# 注釋long_name=2# 注釋不需要對齊dictionary={"foo":1,"long_name":2,}No:foo=1000# 注釋long_name=2# 注釋不需要對齊dictionary={"foo":1,"long_name":2,}Shebang
大部分.py文件不必以#!作為文件的開始. 根據(jù)?PEP-394?, 程序的main文件應(yīng)該以 #!/usr/bin/python2或者 #!/usr/bin/python3開始.
(譯者注: 在計算機科學(xué)中,?Shebang?(也稱為Hashbang)是一個由井號和嘆號構(gòu)成的字符串行(#!), 其出現(xiàn)在文本文件的第一行的前兩個字符. 在文件中存在Shebang的情況下, 類Unix操作系統(tǒng)的程序載入器會分析Shebang后的內(nèi)容, 將這些內(nèi)容作為解釋器指令, 并調(diào)用該指令, 并將載有Shebang的文件路徑作為該解釋器的參數(shù). 例如, 以指令#!/bin/sh開頭的文件在執(zhí)行時會實際調(diào)用/bin/sh程序.)
#!先用于幫助內(nèi)核找到Python解釋器, 但是在導(dǎo)入模塊時, 將會被忽略. 因此只有被直接執(zhí)行的文件中才有必要加入#!.
注釋
確保對模塊, 函數(shù), 方法和行內(nèi)注釋使用正確的風(fēng)格
文檔字符串
Python有一種獨一無二的的注釋方式: 使用文檔字符串. 文檔字符串是包, 模塊, 類或函數(shù)里的第一個語句. 這些字符串可以通過對象的__doc__成員被自動提取, 并且被pydoc所用. (你可以在你的模塊上運行pydoc試一把, 看看它長什么樣). 我們對文檔字符串的慣例是使用三重雙引號"""(?PEP-257?). 一個文檔字符串應(yīng)該這樣組織: 首先是一行以句號, 問號或驚嘆號結(jié)尾的概述(或者該文檔字符串單純只有一行). 接著是一個空行. 接著是文檔字符串剩下的部分, 它應(yīng)該與文檔字符串的第一行的第一個引號對齊. 下面有更多文檔字符串的格式化規(guī)范.
模塊
每個文件應(yīng)該包含一個許可樣板. 根據(jù)項目使用的許可(例如, Apache 2.0, BSD, LGPL, GPL), 選擇合適的樣板.
函數(shù)和方法
下文所指的函數(shù),包括函數(shù), 方法, 以及生成器.
一個函數(shù)必須要有文檔字符串, 除非它滿足以下條件:
外部不可見
非常短小
簡單明了
文檔字符串應(yīng)該包含函數(shù)做什么, 以及輸入和輸出的詳細描述. 通常, 不應(yīng)該描述"怎么做", 除非是一些復(fù)雜的算法. 文檔字符串應(yīng)該提供足夠的信息, 當別人編寫代碼調(diào)用該函數(shù)時, 他不需要看一行代碼, 只要看文檔字符串就可以了. 對于復(fù)雜的代碼, 在代碼旁邊加注釋會比使用文檔字符串更有意義.
關(guān)于函數(shù)的幾個方面應(yīng)該在特定的小節(jié)中進行描述記錄, 這幾個方面如下文所述. 每節(jié)應(yīng)該以一個標題行開始. 標題行以冒號結(jié)尾. 除標題行外, 節(jié)的其他內(nèi)容應(yīng)被縮進2個空格.
Args:?列出每個參數(shù)的名字, 并在名字后使用一個冒號和一個空格, 分隔對該參數(shù)的描述.如果描述太長超過了單行80字符,使用2或者4個空格的懸掛縮進(與文件其他部分保持一致). 描述應(yīng)該包括所需的類型和含義. 如果一個函數(shù)接受*foo(可變長度參數(shù)列表)或者**bar (任意關(guān)鍵字參數(shù)), 應(yīng)該詳細列出*foo和**bar.?Returns: (或者 Yields: 用于生成器)?描述返回值的類型和語義. 如果函數(shù)返回None, 這一部分可以省略.?Raises:?列出與接口有關(guān)的所有異常.?
deffetch_bigtable_rows(big_table,keys,other_silly_variable=None):"""Fetches rows from a Bigtable. Retrieves rows pertaining to the given keys from the Table instance represented by big_table. Silly things may happen if other_silly_variable is not None. Args: big_table: An open Bigtable Table instance. keys: A sequence of strings representing the key of each table row to fetch. other_silly_variable: Another optional variable, that has a much longer name than the other args, and which does nothing. Returns: A dict mapping keys to the corresponding table row data fetched. Each row is represented as a tuple of strings. For example: {'Serak': ('Rigel VII', 'Preparer'), 'Zim': ('Irk', 'Invader'), 'Lrrr': ('Omicron Persei 8', 'Emperor')} If a key from the keys argument is missing from the dictionary, then that row was not found in the table. Raises: IOError: An error occurred accessing the bigtable.Table object. """pass
類
類應(yīng)該在其定義下有一個用于描述該類的文檔字符串. 如果你的類有公共屬性(Attributes), 那么文檔中應(yīng)該有一個屬性(Attributes)段. 并且應(yīng)該遵守和函數(shù)參數(shù)相同的格式.
classSampleClass(object):"""Summary of class here. Longer class information.... Longer class information.... Attributes: likes_spam: A boolean indicating if we like SPAM or not. eggs: An integer count of the eggs we have laid. """def__init__(self,likes_spam=False):"""Inits SampleClass with blah."""self.likes_spam=likes_spamself.eggs=0defpublic_method(self):"""Performs operation blah."""
塊注釋和行注釋
最需要寫注釋的是代碼中那些技巧性的部分. 如果你在下次?代碼審查?的時候必須解釋一下, 那么你應(yīng)該現(xiàn)在就給它寫注釋. 對于復(fù)雜的操作, 應(yīng)該在其操作開始前寫上若干行注釋. 對于不是一目了然的代碼, 應(yīng)在其行尾添加注釋.
# We use a weighted dictionary search to find out where i is in# the array. We extrapolate position based on the largest num# in the array and the array size and then do binary search to# get the exact number.ifi&(i-1)==0:# true iff i is a power of 2
為了提高可讀性, 注釋應(yīng)該至少離開代碼2個空格.
評論
查看更多