Python的初學者,開發(fā)者都應該知道的代碼可讀性提高技巧,本篇主要介紹了如下內(nèi)容:
- PEP 8是什么以及它存在的原因
- 為什么你應該編寫符合PEP 8標準的代碼
- 如何編寫符合PEP 8的代碼
為什么我們需要PEP 8?
PEP 8 的存在是為了提高Python代碼的可讀性的。但為什么可讀性如此重要?為什么編寫可讀代碼是Python語言的指導原則之一?
正如Guido van Rossum所說:“代碼的閱讀頻率遠高于編寫代碼的頻率”。比如,你可能花費幾分鐘或一整天的時間編寫一段代碼。一旦你寫完它,你可能就再也不會寫了,但你肯定要再讀一遍。或者,這段代碼可能仍然是你正在進行的項目的一部分。每次回到該文件時,你都必須記住該代碼的作用以及編寫代碼的原因,因此可讀性非常重要。
如果你是Python的新手,可能很難記住幾天或幾周之前編寫代碼的作用。但如果你遵循PEP 8,你就很好地命名了你的變量,添加了足夠的空格更容易遵循代碼中的邏輯步驟,還可以很好地注釋你的代碼。所有這些都意味著你的代碼更易讀。
如果你正在尋找開發(fā)工作,那么遵循PEP 8尤為重要。編寫清晰易讀的代碼顯示出專業(yè)性。它會告訴你的老板你知道如何很好地構(gòu)建代碼。
如果你有更多編寫Python代碼的經(jīng)驗,那么你可能需要與其他人協(xié)作。其他人可能從未見過你或以前見過你的編碼風格,必須閱讀并理解你的代碼。
命名的規(guī)定
編寫Python代碼時,必須列舉很多東西:變量,函數(shù),類,包等。選擇合理的名字將為你節(jié)省很多時間和精力。你將能夠從名稱中讀懂某個變量,函數(shù)或類所代表的含義。你還可以避免使用那些可能導致后期難以調(diào)試錯誤的不適當?shù)拿Q。
命名樣式
下表總結(jié)了Python代碼中的一些常見類型和命名規(guī)則:

為了編寫可讀代碼,你仍然需要謹慎選擇字母和單詞。除了在代碼中選擇正確的命名樣式外,還必須仔細選擇名稱。
如何選擇名稱
在編寫代碼時,你應該在命名選擇中加入相當多的思考,因為這樣可以使代碼更具可讀性。在Python中命名對象的最佳方法是使用描述性名稱來清楚表明對象所代表的內(nèi)容。
命名變量時,你可能會選擇簡單的單字母小寫名稱,例如x。但是,除非你使用x作為數(shù)學函數(shù)的參數(shù),否則不清楚x代表什么。想象一下,你將一個人的姓名存儲為字符串,并且你希望使用字符串切片來格式化其名稱。你最終會得到這樣的東西:
>>> # Not Recommended
>>> x = 'John Smith'
>>> y, z = x.split()
>>> print(z, y, sep=', ')
'Smith, John'
這是有效的,但你必須跟蹤x,y和z代表的內(nèi)容。這可能讓其他人產(chǎn)生困惑,更明確的名稱選擇將是這樣的:
>>> # Recommended
>>> name = 'John Smith'
>>> first_name, last_name = name.split()
>>> print(last_name, first_name, sep=', ')
'Smith, John'
同樣,為了減少你所做的輸入量,在選擇名稱時使用縮寫是很有幫助的。在下面的例子中,我們定義了一個函數(shù)db(),它接受一個參數(shù)x并將其加倍:
# Not Recommended
def db(x):
return x * 2
乍一看,這似乎是一個明智的選擇。 db()很容易成為double的縮寫。但想象一下,幾天后回到這段代碼,你可能已經(jīng)忘記了你試圖通過這個功能實現(xiàn)的目標,這會花很長時間回想。
以下示例更加清晰。如果你在編寫代碼后幾天回到此代碼,你仍然可以閱讀并理解此函數(shù)的用途:
# Recommended
def multiply_by_two(x):
return x * 2
同樣的理念適用于Python中的所有其他數(shù)據(jù)類型和對象,要始終盡量使用最簡潔但最具描述性的名稱。
代碼布局
如何布置代碼對于它的可讀性有很大的作用。此處,你將學習如何添加垂直空格以提高代碼的可讀性,以及如何處理PEP 8中建議的79字符行限制。
空白行
垂直空白或空行可以極大地提高代碼的可讀性。聚集在一起的代碼可能是壓倒性的,難以閱讀。同樣,代碼中的空行太多會使其看起來非常稀疏,讀者可能需要滾動超過必要的行。以下是關(guān)于如何使用垂直空白的三個關(guān)鍵指南。
1.最外層函數(shù)和類之間要留有兩個空行。最高層函數(shù)和類應該是自包含的,并處理單獨的功能。在它們周圍放置額外的垂直空間是有意義的,因此很明顯它們是分開的:
class MyFirstClass:
pass
class MySecondClass:
pass
def top_level_function():
return None
2.一個類里面的方法之間用一個空行。在一個類中,方法都彼此相關(guān)。最好只在它們之間留一行:
class MyClass:
def first_method(self):
return None
def second_method(self):
return None
3.在函數(shù)內(nèi)使用空白行以顯示清晰的步驟。有時,復雜的函數(shù)必須在return語句之前完成幾個步驟。為了幫助讀者理解函數(shù)內(nèi)部的邏輯,在每個步驟之間留一個空行會很有幫助。
在下面的示例中,有一個計算列表方差的函數(shù)。這是兩步問題,所以我在每個步驟之間留下了一個空行。在return語句之前還有一個空行。這有助于讀者清楚地看到返回的內(nèi)容:
def calculate_variance(number_list):
sum_list = 0
for number in number_list:
sum_list = sum_list + number
mean = sum_list / len(number_list)
sum_squares = 0
for number in number_list:
sum_squares = sum_squares + number**2
mean_squares = sum_squares / len(number_list)
return mean_squares - mean**2
如果仔細使用垂直空白,可以大大提高代碼的可讀性。它有助于讀者直觀地理解你的代碼如何分成幾個部分,以及這些部分如何相互關(guān)聯(lián)。
最大行長度和換行
PEP 8建議行數(shù)限制為79個字符。當然,將語句保持在79個字符以內(nèi)并不總是可行的。 PEP 8給出了允許語句在多行上運行的方法。
如果代碼包含在括號,方括號或大括號中,Python將假定行繼續(xù):
def function(arg_one, arg_two,
arg_three, arg_four):
return arg_one
如果不能使用按規(guī)則繼續(xù),那么你可以使用反斜杠來代替換行:
from mypkg import example1,
example2, example3
如果需要在二元運算符周圍換行,例如 + 和 ,則它應該在運算符之前發(fā)生。數(shù)學家認為在二元運算符之前換行可提高可讀性*。比較以下兩個例子。
下面是在二元運算符之前換行的示例:
# Recommended
total = (first_variable
+ second_variable
- third_variable)
你可以立刻看到正在添加或減去的變量,因為操作符緊挨著正在操作的變量。 現(xiàn)在,讓我們看一個在二元運算符之后換行的示例:
# Not Recommended
total = (first_variable +
second_variable -
third_variable)
在這里,很難看出哪個變量被添加,哪個變量被減去。
縮進
縮進或前導空格在Python中非常重要。Python中代碼行的縮進級別決定了語句如何組合在一起。 請看以下示例:
x = 3
if x > 5:
print('x is larger than 5')
縮進的print語句讓Python知道只有if語句返回True才能執(zhí)行它。相同的縮進會告訴Python在調(diào)用函數(shù)或代碼屬于給定類時要執(zhí)行的代碼。 PEP 8給出的關(guān)鍵縮進規(guī)則如下:
- 使用4個連續(xù)的空格來表示縮進;
- 首選使用空格,再使用Tab;
Tab鍵與空格
如上所述,在縮進代碼時應首先使用空格而不是Tab鍵。你可以在文本編輯器中調(diào)整Tab設(shè)置:當你按Tab鍵時,輸出4個空格而不是Tab符號。
如果你使用的是Python 2,并且混合使用了Tab和空格來縮進代碼,那么在運行它時將不會看到錯誤。為了幫助你檢查一致性,可以在從命令行運行Python 2代碼時添加 -t 標志。當你使用的Tab和空格不一致時,解釋程序?qū)l(fā)出警告:
$ python2 -t code.py
code.py: inconsistent use of tabs and spaces in indentation
如果使用 -tt 標志,則解釋器將發(fā)出錯誤而不是警告,并且你的代碼將不會運行。使用此方法的好處是解釋器會告訴你不一致的位置:
$ python2 -tt code.py
File "code.py", line 3
print(i, j)
^
TabError: inconsistent use of tabs and spaces in indentation
Python 3不允許混合Tab和空格。因此,如果你使用的是Python 3,則會自動發(fā)出以下錯誤:
$ python3 code.py
File "code.py", line 3
print(i, j)
^
TabError: inconsistent use of tabs and spaces in indentation
你可以使用Tab或空格來編寫Python代碼,以表示縮進。但是,如果你使用的是Python 3,則必須與你的選擇保持一致。否則,代碼將無法運行。PEP 8建議始終使用4個連續(xù)空格來表示縮進。
換行后的縮進
當使用換行將行保持在79個字符以下時,使用縮進來提高可讀性是很有用的。它允許讀者區(qū)分兩行代碼和跨越兩行的單行代碼。你可以使用兩種縮進樣式。
第一個是將縮進塊與開口分隔符對齊:
def function(arg_one, arg_two,
arg_three, arg_four):
return arg_one
有時你會發(fā)現(xiàn)只需要4個空格就可以與開口分隔符對齊。這通常發(fā)生在跨越多行的if語句中,因為if,space和opening括號恰巧組成4個字符。在這種情況下,可能很難確定if語句中嵌套代碼塊的開始位置:
>x = 5
if (x > 3 and
x < 10):
print(x)
在這種情況下,PEP 8提供了兩種替代方案來幫助提高可讀性:
1. 在條件之后添加注釋
>x = 5
if (x > 3 and
x < 10):
# Both conditions satisfied
print(x)
2. 在換行中添加額外的縮進
>x = 5
if (x > 3 and
x < 10):
print(x)
第二個換行符后縮進方式是懸掛縮進:
這意味著除了段落或語句中的第一行之外的每一行都是縮進的。你可以使用懸掛縮進來直觀地表示代碼行延續(xù)。下面一個例子:
var = function(
arg_one, arg_two,
arg_three, arg_four)
使用懸掛縮進時,添加額外的縮進以區(qū)分連續(xù)行與函數(shù)內(nèi)包含的代碼。以下示例很難閱讀,因為函數(shù)內(nèi)部的代碼與連續(xù)行的縮進級別相同:
# Not Recommended
def function(
arg_one, arg_two,
arg_three, arg_four):
return arg_one
因此,最好在下一行使用雙縮進。這有助于區(qū)分函數(shù)參數(shù)和函數(shù)體,從而提高可讀性:
def function(
arg_one, arg_two,
arg_three, arg_four):
return arg_one
總結(jié)一下,換行后縮進有兩種方法,第一種是將縮進塊與開口分隔符對齊,第二種是使用懸掛縮進。你可以自由選擇在換行符后使用哪種縮進方法。
在哪里放置右括號
換行允許你斷開括號,方括號或大括號內(nèi)的行。PEP 8為右中括號的位置提供了兩個選項:
1. 使用前一行的第一個非空白字符排列右括號:
list_of_numbers = [
1, 2, 3,
4, 5, 6,
7, 8, 9
]
2. 將右括號與構(gòu)造開始行的第一個字符對齊:
list_of_numbers = [
1, 2, 3,
4, 5, 6,
7, 8, 9
]
可以自由選擇使用的選項,但一致性是關(guān)鍵,所以盡量堅持上述方法之一。
注釋
注釋代碼非常重要,這樣你和任何協(xié)作者都可以理解它。當你或其他人閱讀評論時,他們應該能夠輕松理解注釋所對應的代碼以及它與其余代碼的匹配程度。
以下是在為代碼添加注釋時要記住的一些要點:
- 將注釋和文檔字符串的行長限制為72個字符;
- 使用完整的句子,以大寫字母開頭;
- 如果更改代碼,請務必更新注釋;
塊注釋
使用塊注釋來標注一小部分代碼。當你必須編寫多行代碼來執(zhí)行單個操作(例如從文件導入數(shù)據(jù)或更新數(shù)據(jù)庫條目)時,它們非常有用。它們很重要,因為它們可以幫助其他人理解給定代碼塊的用途和功能。
PEP 8為編寫塊注釋提供了以下規(guī)則:
- 將塊注釋縮進到與它們描述的代碼相同的級別;
- #后面加單個空格后開始注釋;
- 用包含單個#的行分隔段落;
這是一個解釋for循環(huán)功能的塊注釋。請注意,句子換行到新行以保留79個字符行限制:
for i in range(0, 10):
# Loop over i ten times and print out the value of i, followed by a
# new line character
print(i, '
')
有時,如果代碼是非常技術(shù)性的,那么有必要在塊注釋中使用多個段落:
def quadratic(a, b, c, x):
# Calculate the solution to a quadratic equation using the quadratic
# formula.
#
# There are always two solutions to a quadratic equation, x_1 and x_2.
x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
return x_1, x_2
如果你對使用哪種注釋類型更適合存在疑問,那么塊注釋通常是可行的方法。盡可能在整個代碼中使用它們,但如果你對代碼進行了更改,也請務必更新它們。
行注釋
行注釋解釋了一段代碼中的單個語句。它們有助于提醒你,或向其他人解釋為什么需要某行代碼。以下是PEP 8對它們的建議:
- 與代碼寫在同一行;
- 使用兩個或多個空格將代碼與行注釋分開;
- #后加單個空格,然后進行行注釋;
- 不要用它們來解釋已經(jīng)很明顯的問題;
以下是行注釋的示例:
x = 5 # This is an inline comment
有時,行注釋似乎是必要的,但你可以使用更好的命名規(guī)則。比如,這是一個例子:
x = 'John Smith' # Student Name
這里,行注釋確實提供了額外的信息。但是,使用x作為人名的變量名是不好的做法。如果重命名變量,則無需行注釋:
student_name = 'John Smith'
最后,像這樣的行注釋是不好的做法,因為它們注釋了明顯且混亂的代碼:
empty_list = [] # Initialize empty list
x = 5
x = x * 5 # Multiply x by 5
行注釋比塊注釋更具體,但很容易在不需要時添加它們,這會導致混亂,而你可以總是使用塊注釋,而不必擔心這些。因此,除非確定需要使用行注釋,否則更多使用塊注釋,則代碼更可能符合PEP 8。
文檔字符串
文檔字符串是用雙(""")或單引號(''')括起來的字符串,它們出現(xiàn)在任何函數(shù),類,方法或模塊的第一行。你可以使用它們來解釋和記錄一個特定的代碼塊。
適用于文檔字符串的最重要規(guī)則如下:
- 環(huán)繞文檔字符串,兩邊都有三個雙引號,如 """ 這是一個文檔字符串 """;
- 為所有公共模塊,函數(shù),類和方法編寫它們;
- 將單行結(jié)束多行文檔字符串的 """ 放在一行上:
def quadratic(a, b, c, x):
"""Solve quadratic equation via the quadratic formula.
A quadratic equation has the following form:
ax**2 + bx + c = 0
There always two solutions to a quadratic equation: x_1 & x_2.
"""
x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
return x_1, x_2
- 對于單行文檔字符串,請將 """ 保留在同一行:
def quadratic(a, b, c, x):
"""Use the quadratic formula"""
x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
return x_1, x_2
表達式和語句的空格
空格在表達式和語句中正確使用時非常有用。如果沒有足夠的空白,那么代碼可能難以閱讀,因為它們都聚集在一起。如果空白太多,那么在語句中可能難以在視覺上組合相關(guān)術(shù)語。
二元運算符兩邊的空白
以下二元運算符兩邊都有一個空格:
- 賦值運算符(=,+=, -=)
- 比較運算符(==,=!,>,<,>=,<=)和(is,is not,in,not in)
- 布爾運算法(and,not,or)
如果語句中有多個運算符,則在每個運算符之前和之后添加單個空格可能會讓人感到困惑。相反,最好只在優(yōu)先級最低的運算符兩邊添加空格,尤其是在執(zhí)行數(shù)學運算時。以下是幾個例子:
# Recommended
y = x**2 + 5
z = (x+y) * (x-y)
# Not Recommended
y = x ** 2 + 5
z = (x + y) * (x - y)
你還可以將此應用于有多個條件的if語句:
# Not recommended
if x > 5 and x % 2 == 0:
print('x is larger than 5 and divisible by 2!')
在上面的示例中,and 運算符具有最低優(yōu)先級。因此,可以更清楚地表達if語句如下:
# Recommended
if x>5 and x%2==0:
print('x is larger than 5 and divisible by 2!')
你可以自由選擇哪個更清晰,但需要注意的是必須在運算符的任何一側(cè)使用相同數(shù)量的空格。以下是不可接受的:
# Definitely do not do this!
if x >5 and x% 2== 0:
print('x is larger than 5 and divisible by 2!')
在切片中,冒號充當二元運算符。因此,上面所說的規(guī)則同樣適用,任何一方都應該有相同數(shù)量的空白。以下列表切片示例:
list[3:4]
# Treat the colon as the operator with lowest priority
list[x+1 : x+2]
# In an extended slice, both colons must be
# surrounded by the same amount of whitespace
list[3:4:5]
list[x+1 : x+2 : x+3]
# The space is omitted if a slice parameter is omitted
list[x+1 : x+2 :]
何時避免添加空格
在某些情況下,添加空格會使代碼更難以閱讀。太多的空格會使代碼過于稀疏而難以理解。PEP 8總結(jié)了空白不合適的非常明顯的例子。
避免添加空格的最重要的地方是在一行的末尾,這稱為尾部空格。它是不容易察覺的,可能產(chǎn)生難以追蹤的錯誤。
以下總結(jié)了一些應避免添加空格的情況:
- 緊靠括號,括號或大括號內(nèi):
# Recommended
my_list = [1, 2, 3]
# Not recommended
my_list = [ 1, 2, 3, ]
- 在逗號,分號或冒號之前:
x = 5
y = 6
# Recommended
print(x, y)
# Not recommended
print(x , y)
- 在打開函數(shù)調(diào)用的參數(shù)列表的開括號之前:
def double(x):
return x * 2
# Recommended
double(3)
# Not recommended
double (3)
- 在開始索引或切片的開括號之前:
# Recommended
list[3]
# Not recommended
list [3]
- 在末尾逗號和右括號之間:
# Recommended
tuple = (1,)
# Not recommended
tuple = (1, )
- 要對齊賦值運算符:
# Recommended
var1 = 5
var2 = 6
some_long_var = 7
# Not recommended
var1 = 5
var2 = 6
some_long_var = 7
確保代碼中的任何位置都沒有尾部空格。在其他情況下,PEP 8不鼓勵添加額外的空格,例如立即在括號內(nèi),以及逗號和冒號之前。你也應該永遠不要添加額外的空格為了對齊運算符。
編程建議
你經(jīng)常會發(fā)現(xiàn)有幾種方法可以在Python中執(zhí)行相同的操作(以及任何其他編程語言)。下面你將看到PEP 8提供的一些建議,以消除這種歧義并保持一致性。
1. 不要使用等價運算符==將布爾值與True或False進行比較。你經(jīng)常需要檢查布爾值是True還是False。
# Not Recommended
my_bool = 6 > 5
if my_bool == True:
return '6 is bigger than 5'
這里不需要使用等價運算符==,bool只能取值True或False,因此寫下面的內(nèi)容就足夠了,這種使用布爾值執(zhí)行if語句的方法需要更少的代碼并且更簡單。
# Recommended
if my_bool:
return '6 is bigger than 5'
2. 在if語句中直接判斷空序列是否為假。如果要檢查列表是否為空,則可能需要檢查列表的長度。如果列表為空,則其長度為0,在if語句中使用時等于False。這是一個例子:
# Not Recommended
my_list = []
if not len(my_list):
print('List is empty!')
但是,在Python中,任何空列表,字符串或元組都是假的。因此,我們可以給出一個更簡單的替代方案:
# Recommended
my_list = []
if not my_list:
print('List is empty!')
雖然兩個例子都打印出來了,第二個選項更簡單,所以PEP 8鼓勵使用它。
3. 在if語句中使用 is not 而非 not...is。如果你要檢查變量是否具有已定義的值,則有兩個選項。第一個是使用 x is not None,如下例所示:
# Recommended
if x is not None:
return 'x exists!'
第二種選擇是 x is None,然后根據(jù) not 結(jié)果得到if語句:
# Not Recommended
if not x is None:
return 'x exists!'
雖然兩個選項都將被正確評估,但第一個選項更簡單。
4. 當你的意思是x is not None 的時候,不要使用if x。有時,你可能擁有一個默認情況下參數(shù)為None的函數(shù)。檢查這樣的參數(shù)arg是否被賦予不同值時常見的錯誤是使用以下內(nèi)容:
# Not Recommended
if arg:
# Do something with arg...
此代碼檢查arg是否為真。相反,你要檢查arg是否為None,因此最好使用以下內(nèi)容:
# Recommended
if arg is not None:
# Do something with arg...
這里犯的錯誤是假設(shè)了 not None和 truthy 是等價的。你可以設(shè)置arg = []。如上所述,空列表在Python中被評估為假的。因此,即使已經(jīng)分配了參數(shù)arg,也不滿足條件,因此不會執(zhí)行if語句主體中的代碼。
5. 使用.startswith()和.endswith()而不是切片。如果你嘗試檢查字符串單詞是否帶有前綴或帶有后綴的單詞cat,那么使用列表切片似乎是明智的。但是,列表切片容易出錯,你必須對前綴或后綴中的字符數(shù)進行硬編碼。對于那些不太熟悉Python列表切片的人來說,你還想要實現(xiàn)的目標也不清楚:
# Not Recommended
if word[:3] == 'cat':
print('The word starts with "cat"')
然后,這不像使用.startswith()那樣可讀:
# Recommended
if word.startswith('cat'):
print('The word starts with "cat"')
當檢查后綴時,同樣的原則也適用。下面的示例總結(jié)了如何檢查字符串是否以jpg結(jié)尾:
# Not Recommended
if file_name[-3:] == 'jpg':
print('The file is a JPEG')
雖然結(jié)果是正確的,但符號有點難以閱讀。相反,你可以使用.endswith(),如下例所示:
# Recommended
if file_name.endswith('jpg'):
print('The file is a JPEG')
與大多數(shù)這些編程建議一樣,目標是可讀性和簡單性。在Python中,有許多不同的方法可以執(zhí)行相同的操作,因此有關(guān)選擇哪種方法的指南很有幫助。
何時忽略PEP 8?
對這個問題的回答:永遠不會。如果遵循PEP 8,可以保證你將擁有干凈,專業(yè)和可讀的代碼。這將使你以及合作者和潛在雇主都受益。
但是,在以下情況下,PEP 8中的某些指南很不方便:
- 如果遵守PEP 8將破壞與現(xiàn)有軟件的兼容性;
- 如果圍繞你正在處理的內(nèi)容的代碼與PEP 8不一致;
- 如果代碼需要與舊版本的Python保持兼容;
幫助你的代碼遵循PEP 8的提示和技巧
PEP 8標準有很多內(nèi)容,在開發(fā)代碼時,記住所有這些規(guī)則可能是一項艱巨的任務。將過去的項目更新為符合PEP 8特別耗時。幸運的是,有些工具可以幫助加快這一過程。你可以使用兩類工具來強制執(zhí)行PEP 8:linters 和autoformatters。
Linters
Linters是分析代碼和標記錯誤的程序,它提供了有關(guān)如何修復錯誤的建議。當作為文本編輯器的擴展安裝時,Linters特別有用,因為它們在你編寫時標記錯誤和樣式問題。下面你將看到Linkers的工作原理,然后和文本編輯器擴展的鏈接。
最好Linters的Python代碼如下:
pycodestyle是一個根據(jù)PEP 8中的某些樣式約定來檢查Python代碼的工具。使用pip安裝pycodestyle:
$ pip install pycodestyle
可以使用以下命令終端運行pycodestyle:
$ pycodestyle code.py
code.py:1:17: E231 missing whitespace after ','
code.py:2:21: E231 missing whitespace after ','
code.py:6:19: E711 comparison to None should be 'if cond is None:'
flake8是一個結(jié)合了debugger,pyflakes和pycodestyle的工具。使用pip安裝flake8:
$ pip install flake8
使用以下命令從終端運行flake8:
$ flake8 code.py
code.py:1:17: E231 missing whitespace after ','
code.py:2:21: E231 missing whitespace after ','
code.py:3:17: E999 SyntaxError: invalid syntax
code.py:6:19: E711 comparison to None should be 'if cond is None:':
Autoformatters
Autoformatters是重構(gòu)ni1的代碼以自動符合PEP 8的程序。一旦這樣的程序是black,它按照PEP 8中的大多數(shù)規(guī)則自動編碼代碼。一個很大的區(qū)別是它將行長度限制為88個字符,而不是79。但是,你可以通過添加命令行標志來覆蓋它,就像你一樣我將在下面的例子中看到。
使用pip安裝black。它需要Python 3.6+才能運行:
$ pip install black
它可以通過命令行運行,就像Linters一樣。假設(shè)你從名為code.py的文件中開始使用以下不符合PEP 8的代碼:
for i in range(0,3):
for j in range(0,3):
if (i==2):
print(i,j)
然后,您可以通過命令行運行以下命令:
$ black code.py
reformatted code.py
All done!
code.py將自動重新格式化為如下所示:
for i in range(0, 3):
for j in range(0, 3):
if i == 2:
print(i, j)
如果要更改行長度限制,則可以使用--line-length標志:
$ black --line-length=79 code.py
reformatted code.py
All done!
另外兩個autoformatters,autopep8和yapf,執(zhí)行與black相似的操作。
總結(jié)
本篇主要介紹了如下內(nèi)容:
- PEP 8是什么以及它存在的原因;
- 為什么你應該編寫符合PEP 8標準的代碼;
- 如何編寫符合PEP 8的代碼;
除此之外,還介紹了如何使用linters和autoformatters根據(jù)PEP 8指南檢查代碼。
如果您想了解有關(guān)PEP 8的更多信息,那么你可以閱讀完整的文檔,或訪問pep8.org,它包含相同的信息,但格式很好。