PEP8——Python程式碼規範

Inside_Zhang發表於2015-11-12

統一且設計良好的程式碼規範,是一種優良的程式設計習慣。

PyCharm這一Python IDE使用的正是著名的PEP8程式碼規範,我們會看到,當有不符合規範的程式碼出現時,編譯器會以灰色下劃波浪線給出相關提示,本文即告訴你如何寫出沒有灰色警告線的至少看上去很美的程式碼樣式。


這裡寫圖片描述


縮排(indentation)

使用四個空格表示每個縮排級別。

Yes

# 使用開分隔符(opening delimiter)進行對齊

foo = long_func_name(var_one, var_two,
                     var_three, var_four)

# 使用更多的縮排以和其他的程式碼單元區別開來
# 如下例的,引數部分比函式體多四個縮排以和函式體進行區別
def long_func_name(
        var_one, var_two, var_three,
        var_four)
    print(var_one)

# 懸掛縮排(hanging indents):增加一個縮排級別
foo = long_func_name(
    var_one, var_two, 
    var_three, var_four)
# 或者:
foo = long_func_name(
    var_one, var_two,
    var_three, var_four
)


a = [1, 2, 3,
     4, 5, 6]
a = [
    1, 2, 3,
    4, 5, 6
]

No

# 當不適用垂直對齊時,禁止在第一行使用引數
# 換句話說,在垂直對齊時,才可在第一行使用引數
foo = lone_func_name(var_one, var_two, 
    var_three, var_four)

# 當縮排不足以區分程式碼結構時,增加一個縮排級別
def long_func_name(
    var_one, var_two, var_three
    var_four):
    print(var_one)

最大行長度

所有行的最大長度均為79個字元。

with open('') as file_1, \
     open('') as file_2:
    file_2.write(file_1.read())

使用正確的換行位置。推薦的位置在二元操作符(binary operator,如下述程式碼中的andor以及%)之後,而不是在它們之前:

class Rectangle(Shape):
    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
                color == 'red' and emphasis == 'strong' or
                height > 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 -- values are %s, %s" %
                             (width, height))
        Shape.__init__(self, width, height, color,
                       emphasis, highlight)

空行

  • 頂級函式(當前檔案中的第一個函式)或者頂級類(當前檔案的第一個類)之前要有兩個空行

  • 定義在類內部的函式(成員函式)之間要留有一個空行

  • 可以使用額外的空行(但要注意節制)以區分不同的函式組,

  • 在一堆只有一行的函式之間不要使用空行(比如一些函式的空實現)

  • 在函式內部使用空行,來標識不同的邏輯單元

imports

  • 在獨立的行中匯入不同的包

Yes

import sys
import os

No

import sys, os

但從一個包中新增不同的模組或者函式也是允許的:

from subprocess import Popen, PIPE
  • import檔案應當總是位於檔案的首部,僅在模組備註和文件之後,在模組的全域性變數和常量之前的位置

import檔案的順序:
1. 標準庫(如sys、os)
2. 相關的第三方的庫(如numpy、pandas、matplotlib)
3. 自定義的.py檔案或者自定義的庫

以組的形式標識上述三種import檔案,也即是用一個空行隔開

  • 推薦使用絕對路徑包含,因為可讀性更好,並且不易出錯。
import mypkg.sibling
from mypkg import sibling 
from mypkg.sibling import example

然而,外部的相對包含也是一種可接受的替換,尤其是處理複雜的包層次時,也即是絕對包含將造成不必要的繁瑣。

from . import sibling
from .sibling import example        # .表示當前路徑

標準庫不存在複雜的包層次關係,應當總是使用其絕對匯入路徑。

  • 應當避免萬用字元匯入檔案

字串

在python中,不對單引號和雙引號作區分,PEP的程式碼規範也不對此有所推薦。任選其一,統一使用即可。然而,當一個字串包含單引號或者雙引號時,使用另外一種方式避免轉義符(\)的使用,以提高可讀性。

表示式中的空格

在下述條件下,避免使用空格:

  • 緊跟著大括號、中括號和小括號之前

Yes

spam(ham[1], {eggs: 90})

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 
  • 切片中的冒號

在切片中冒號可視為一個二元操作符(binary operator),兩邊應用等數量的空格。

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]

其他的建議

  • 總是在如下的二元操作符的兩邊使用單空格:

    1. 賦值:=
    2. 增量賦值:+=-=
    3. 比較:==, <, >, !=, <>, in , is
    4. 布林:andornot
  • 不要使用空格,當被用來標識一個關鍵字引數(使用函式)或者一個預設引數賦值(定義函式)

Yes

def complex(real, imag=0.):
    return magic(r=real, i=imag)

No

def complex(real, imag = 0.):
    return magic(r = real, i = imag)

文件

  • 為所有公共模組或者函式、類以及方法編寫文件。不必為非公共方法編寫doc文件,但應有一個註釋描述演算法的功能,這條註釋應當出現在def之後

  • 結尾的"""應當獨佔一行

"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.
"""

References

[1] <PEP 0008 – Style Guide for Python Code>

相關文章