Python Coding Style (Reference to PEP 8)
程式碼區塊順序
一個.py
檔視為一個模組,一個模組的程式碼區塊由上而下依序為:
- Module Docstrings
- from
__future__
import ... - Module Level Dunders
- Imports
- Global Variables and Constants
- Functions, Methods and Their Docstrings
範例:
# Module Docstrings
"""Example module docstrings
the description of module
"""
# from __future__ import ...
from __future__ import division
# Module Level Dunders
__all__ = ['some_variable', 'some_method']
__version__ = '0.1'
__author__ = 'Cardinal Biggles'
# Imports
import os
import sys
import tensorflow as tf
from polls.models import Question
# Global Variables and Constants
CONSTANT_ONE = 3.14159
CONSTANT_TWO = 'Hello'
# Functions, Methods and Docstrings
class SomeClass:
"""class docstrings
the description of class
"""
def __init__(self):
pass
def some_mothod():
"""mothod docstrings
the description of method
"""
pass
補充說明:
from __future__ import
表示引用 Python 未來即將更新的一些新功能。__all__
定義該模組哪些類別、變數或是方法可以被其他模組引用。
Imports
import
每一種套件必須分行 import。
正確:
import os
import sys
錯誤:
import os, sys
from import
同一個路徑下需要使用到的類別或方法必須一起 import。
範例:
from flask import Flask, request
import順序
各種類套件必須以下方順序 import,並且應該使用空白行區分各種類套件。
- 標準套件
- 第三方套件
- 自行開發的套件
範例:
import os
import sys
import tensorflow as tf
from keras.models import load_model
from polls.models import Question, Choice
字串引號
對於Python
的字串來說,使用'
和"
是相同的。PEP 8
並沒有硬性規定字串必須使用哪種引號,但是PEP 257
有規定Docstrings
必須使用三個雙引號"
。
空白字元
適當地使用空白字元可以增加程式碼的可讀性,相關範例可參考 空白字元使用範例。
註解
區塊註解
如果一次要對多行程式碼進行註解,在多行程式碼之前以# 註解內容
進行註解,#
與註解內容中間要有一個空白。
範例:
# wait for threads actually stop.
coord.request_stop()
coord.join(threads)
單行註解
單行程式碼註解,在程式碼之後,加上兩個以上的空白,並以# 註解內容
進行註解。
範例:
all_images.tofile('train.dat') # save train data to binary format.
Docstrings
公開(public)的模組(modules)、類別(classes)和方法(methods)須使用Docstrings
進行說明,非公開(non-public)則不須寫Docstrings
,但應該寫個簡單的註解以瞭解該方法作用。
模組(Module)
"""module docstrings
the description of module
"""
類別(Class) 和 方法(Method)
class SomeClass:
"""class docstrings
the description of class
"""
def some_mothod():
"""mothod docstrings
the description of method
"""
使用help()
或.__doc__
可取得定義的Docstrings
內容。
更詳細的描述寫法可參考 描述範例。
命名規則
套件名稱(Package Names)
這裡的套件
指的是模組所在目錄
,目錄名稱盡量簡短
,且全部必須小寫
。
模組名稱(Module Names)
這裡的模組
指的是一個.py檔案
,檔名盡量簡短
,且全部必須小寫
,如果名稱太長可使用底線_
增加可讀性。
類別名稱(Class Names)
須遵守CapWords
規則,例如:class MyClass(object):
。
例外名稱(Exception Names)
Exception
通常是個Class
,須遵守Class
的規則,並在後綴加上Error
。例如:class ExampleError(Exception):
。
全域變數(Global Variables)
全部皆小寫
,有意義的單字須以底線_
隔開。
常數(Constants)
全部皆大寫
,有意義的單字須以底線_
隔開。
函式名稱(Function Names)
全部皆小寫
,有意義的單字須以底線_
隔開。
方法名稱和實例變數(Method Names and Instance Variables)
全部皆小寫
,有意義的單字須以底線_
隔開。
函式和方法參數(Function and Method Arguments)
instance methods
第一個參數必須命名為self
。class methods
第一個參數必須命名為cls
。
範例:
class Staff:
def __init__(self, staff_name):
self.staff_name = staff_name
def say_hello(self):
print("Hello", self.name)
@staticmethod
def static_method():
print("This is static method.")
@classmethod
def class_method(cls):
print("This is class method.")
print("The class name is", cls.__name__)
Staff.static_method() # static method
Staff.class_method() # class method
s = Staff('Bob')
s.say_hello() # instance method
縮排(Indentation)
多行資料
範例:
list = [
1, 2, 3,
4, 5, 6,
7, 8, 9,
]
定義函式和方法
定義的函式和方法參數過多需要換行,必須縮排兩次與當中的代碼有所區別。
範例:
def long_function_name(
parm_one, parm_two,
parm_three, parm_four):
print("do something")
呼叫函式或方法
呼叫的函式和方法參數過多需要換行。
方式ㄧ:換行後,其後的參數必須對齊開頭的左括號(
。
foo = long_function_name("var_one", "var_two",
"var_three", "var_four")
方式二:以多列資料方式呈現。
foo = long_function_name(
"var_one", "var_two",
"var_three", "var_four"
)
if、assert、with as
if、assert、with as等陳述句,當中的條件或代碼過長需要換行。
方式ㄧ:其後的條件必須縮排兩次與if
中的代碼有所區別。
if ("this_is_first_condition"
and "this_is_second_condition"):
print("do something")
方式二:以反斜線\
作為換行時的標記,換行後須對齊左括號(
。
if ("this_is_first_condition" \
and "this_is_second_condition"):
print("do something")
二元運算子
二元運算子必須與準備運算的運算元同一列,可讀性較高。
範例:
income = (gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest)