
# 代碼約定
在Python社區中有許多關于代碼風格的約定。如果你寫過一段時間Python了,那么也許對此已經有些了解。
我會簡單介紹一下,同時給你一些URL鏈接,從中你可以找到關于這個話題的詳細信息。
## 讓我們提出一個PEP!
**PEP**全稱是“Python Enhancement Proposal”(Python增強提案)。你可以在[python.org](http://www.python.org/dev/peps/)上找到它們以及對應的索引目錄。
PEP在索引目錄中按照數字編號排列,包括了元PEP(meta-PEP,討論關于PEP的細節)。與之對應的是技術PEP(technical PEP),思考的是諸如Python內部實現的改良這樣的話題。
有一些PEP,比如PEP 8和PEP 257,影響了Python代碼風格的標準。
PEP 8包括了Python代碼風格的規約。
而PEP 257包括了文檔字符串(docstrings, 在Python中給代碼加文檔的標準方式)的規約。
### PEP 8: Python代碼風格規約
PEP 8是對Python代碼風格的官方規約。
我建議你閱讀它并將之付諸在Flask項目(以及其他Python項目)的開發實踐中。
當項目規模膨脹到多個包含成百上千行代碼的文件時,這樣做會使你的代碼更加工整、了然。畢竟PEP 8的建議都是圍繞著實現更加可讀的代碼這個目標。
另外,如果你的項目準備開源,潛在的奉獻者(contributors)會很高興看到你的代碼是遵循PEP 8的。
一個至關重要的建議是每級縮進使用4個空格。不要使用tab。
如果你打破了這個規約,它將會成為你(以及你的隊友)在項目間切換的一個負擔。
這種不一致一向是任意語言心中的痛,但是對于Python,一門著重留白的語言,這是一個不可承受之重。
因為tab與space之間的混搭會導致不可預期且難以排查的錯誤。
### PEP 257: 文檔字符串規約
PEP 257 覆蓋了Python的另一項標準:**docstrings**。
你可以閱讀PEP中的定義和相關建議,不過這里會給一個例子來展示一個文檔字符串應該是怎樣的:
```python
def launch_rocket():
"""主要的火箭發射調度器
啟動發射火箭所需的每一個步驟。
"""
# [...]
```
這種風格的文檔字符串可以通過一些諸如[Sphinx](http://sphinx-doc.org/)的軟件來生成不同格式的文檔。
同時它們也有助于讓你的代碼更加工整。
> 參見
> * PEP 8 <http://legacy.python.org/dev/peps/pep-0008/>
> * PEP 257 <http://legacy.python.org/dev/peps/pep-0257/>
> * Sphinx <http://sphinx-doc.org/>,一個文檔生成器,同出于Flask作者之手
## 相對形式的import
開發Flask應用時,使用相對形式的import會讓你的生活更加輕松。
原因很簡單。之前,當需要import一個內部模塊時,你也許要顯式指明應用的包名(the app's package name)。假設你想要從*myapp/models.py*中導入`User`模型:
```python
# 使用絕對路徑來導入User
from myapp.models import User
```
用了相對形式的import后,你可以使用點標記法:第一個`.`來表示當前目錄,之后的每一個`.`表示下一個父目錄。
```python
# 使用相對路徑來導入User
from .models import User
```
這種做法的好處在于使得package變得更加模塊化了。
現在你可以重命名你的package并在別的項目中重用模塊,而無需忍受更新被硬編碼的包名之苦。
> 參見
> * 你可以在PEP 328的[這一節](http://www.python.org/dev/peps/pep-0328/#guido-s-decision)里讀到更多關于相對形式的import的語法
> * 在寫作本書的過程中,我碰巧在這個Tweet上面看到了一個使用相對形式的import的好處:
> <https://twitter.com/dabeaz/status/372059407711887360>
> Just had to rename our whole package. Took 1 second. Package relative imports FTW!
## 總結
* 盡量遵循PEP 8中的代碼風格規約。
* 盡量遵循PEP 257中的文檔字符串規約。
* 使用相對形式的import來import你的應用中的內部模塊。