天天看點

python 全部縮進一行_Python代碼這樣寫才規範優雅! (一)

python 全部縮進一行_Python代碼這樣寫才規範優雅! (一)

我們在寫 Python 代碼時,有沒有刻意注意過代碼規範性呢?

一份不規範的代碼不僅給自己培養了不好的習慣,由于 Python 理應是優雅的,不規範的代碼不僅不夠優雅,還影響了了閱讀代碼的可讀性。更可怕的是不友善協作程式設計。

關于 Python 程式設計規範,可以學習 PEP 8 風格指南。

PEP 是 Python Enhancement Proposal 的縮寫,通常翻譯為“Python增強提案”。每個 PEP 都是一份為 Python 社群提供的指導 Python 往更好的方向發展的技術文檔,其中的第 8 号增強提案(PEP 8)是針對 Python 語言編訂的代碼風格指南。

參考:

https://www.python.org/dev/peps/pep-0008/

Python PEP8編碼規範的内容如下:

1. Introduction 介紹2. A Foolish Consistency is the Hobgoblin of Little Minds 盡信書,則不如無書3. Code lay-out 代碼布局3.1 Indentation 縮進3.2 Tabs or Spaces? 制表符還是空格?3.3 Maximum Line Length 行的最大長度3.4 Should a line break before or after a binary operator? 在二進制運算符之前應該換行嗎?3.5 Blank Lines 空行3.6 Source File Encoding 源檔案編碼3.7 Imports 導入3.8 Module level dunder names 子產品級的“呆”名4. String Quotes 字元串引号5. Whitespace in Expressions and Statements 表達式和語句中的空格5.1 Pet Peeves 不能忍受的事情5.2 Other Recommendations 其他建議6. Comments 注釋6.1 Block Comments 塊注釋6.2 Inline Comments 行内注釋6.3 Documentation Strings 文檔字元串7. Naming Conventions 命名規範7.1 Overriding Principle 最重要的原則7.2 Descriptive: Naming Styles 描述:命名風格7.3 Prescriptive: Naming Conventions 約定俗成:命名約定7.4 Public and internal interfaces 公共和内部的接口8. Programming Recommendations 程式設計建議8.1 Function Annotations 功能注釋9. 參考

1. Introduction 介紹

本文提供的 Python 代碼編碼規範基于 Python 主要發行版本的标準庫。Python 的 C 語言實作的 C 代碼規範請檢視相應的 PEP 指南。

這篇文檔以及PEP 257(文檔字元串的規範)改編自 Guido 原始的《Python Style Guide》一文,同時添加了一些來自 Barry 的風格指南。

這篇規範指南随着時間的推移而逐漸演變,随着語言本身的變化,過去的約定也被淘汰了。

許多項目有自己的編碼規範,在出現規範沖突時,項目自身的規範優先。

2. A Foolish Consistency is the Hobgoblin of Little Minds 盡信書,則不如無書

Guido的一條重要的見解是代碼閱讀比寫更加頻繁。這裡提供的指導原則主要用于提升代碼的可讀性,使得在大量的Python代碼中保持一緻。就像PEP20提到的,“Readability counts”。

這是一份關于一緻性的風格指南。這份風格指南的風格一緻性是非常重要的。更重要的是項目的風格一緻性。在一個子產品或函數的風格一緻性是最重要的。

然而,應該知道什麼時候應該不一緻,有時候編碼規範的建議并不适用。當存在模棱兩可的情況時,使用自己的判斷。看看其他的示例再決定哪一種是最好的,不要羞于發問。

特别是不要為了遵守PEP約定而破壞相容性!

幾個很好的理由去忽略特定的規則:

當遵循這份指南之後代碼的可讀性變差,甚至是遵循PEP規範的人也覺得可讀性差。

與周圍的代碼保持一緻(也可能出于曆史原因),盡管這也是清理他人混亂(真正的Xtreme Programming風格)的一個機會。

有問題的代碼出現在發現編碼規範之前,而且也沒有充足的理由去修改他們。

當代碼需要相容不支援編碼規範建議的老版本Python。

3 Code lay-out 代碼布局

3.1 Indentation 縮進

每一級縮進使用4個空格。

續行應該與其包裹元素對齊,要麼使用圓括号、方括号和花括号内的隐式行連接配接來垂直對齊,要麼使用挂行縮進對齊。當使用挂行縮進時,應該考慮到第一行不應該有參數,以及使用縮進以區分自己是續行。

#推薦的寫法:# 與左括号對齊foo = long_function_name(var_one, var_two,                         var_three, var_four)# 用更多的縮進來與其他行區分def long_function_name(         var_one, var_two, var_three,         var_four):    print(var_one)# 挂行縮進應該再換一行foo = long_function_name(    var_one, var_two,    var_three, var_four)

#不推薦的寫法:# 沒有使用垂直對齊時,禁止把參數放在第一行foo = long_function_name(var_one, var_two,    var_three, var_four)# 當縮進沒有與其他行區分時,要增加縮進def long_function_name(     var_one, var_two, var_three,     var_four):    print(var_one)

四空格的規則對于續行是可選的。

# 挂行縮進不一定要用4個空格foo = long_function_name(  var_one, var_two,  var_three, var_four)

當if語句的條件部分長到需要換行寫的時候,注意可以在兩個字元關鍵字的連接配接處(比如if),增加一個空格,再增加一個左括号來創造一個4空格縮進的多行條件。這會與if語句内同樣使用4空格縮進的代碼産生視覺沖突。PEP沒有明确指明要如何區分if的條件代碼和内嵌代碼。可使用的選項包括但不限于下面幾種情況:

# 沒有額外的縮進if (this_is_one_thing and    that_is_another_thing):    do_something()# 增加一個注釋,在能提供文法高亮的編輯器中可以有一些區分if (this_is_one_thing and    that_is_another_thing):    # Since both conditions are true, we can frobnicate.    do_something()# 在條件判斷的語句添加額外的縮進if (this_is_one_thing        and that_is_another_thing):    do_something()

在多行結構中的大括号/中括号/小括号的右括号可以與内容對齊單獨起一行作為最後一行的第一個字元,就像這樣:

my_list = [    1, 2, 3,    4, 5, 6,    ]result = some_function_that_takes_arguments(    'a', 'b', 'c',    'd', 'e', 'f',    )

或者也可以與多行結構的第一行第一個字元對齊,就像這樣:

my_list = [    1, 2, 3,    4, 5, 6,]result = some_function_that_takes_arguments(    'a', 'b', 'c',    'd', 'e', 'f',)

3.2 Tabs or Spaces? 制表符還是空格?

空格是首選的縮進方式。 

制表符隻能用于與同樣使用制表符縮進的代碼保持一緻。 

Python3不允許同時使用空格和制表符的縮進。 

混合使用制表符和空格縮進的Python2代碼應該統一轉成空格。 

當在指令行加入-t選項執行Python2時,它會發出關于非法混用制表符與空格的警告。當使用–tt時,這些警告會變成錯誤。強烈建議使用這樣的參數。

3.3 Maximum Line Length 行的最大長度

所有行限制的最大字元數為79。 

沒有結構化限制的大塊文本(文檔字元或者注釋),每行的最大字元數限制在72。 

限制編輯器視窗寬度可以使多個檔案并行打開,并且在使用代碼檢查工具(在相鄰列中顯示這兩個版本)時工作得很好。 

大多數工具中的預設封裝破壞了代碼的可視化結構,使代碼更難以了解。避免使用編輯器中預設配置的80視窗寬度,即使工具在幫你折行時在最後一列放了一個标記符。某些基于Web的工具可能根本不提供動态折行。 

一些團隊更喜歡較長的行寬。如果代碼主要由一個團隊維護,那這個問題就能達成一緻,可以把行長度從80增加到100個字元(更有效的做法是将行最大長度增加到99個字元),前提是注釋和文檔字元串依然以72字元折行。 

Python标準庫比較保守,需要将行寬限制在79個字元(文檔/注釋限制在72)。 

較長的代碼行選擇Python在小括号,中括号以及大括号中的隐式續行方式。通過小括号内表達式的換行方式将長串折成多行。這種方式應該優先使用,而不是使用反斜杠續行。 

反斜杠有時依然很有用。比如,比較長的,多個with狀态語句,不能使用隐式續行,是以反斜杠是可以接受的:

with open('/path/to/some/file/you/want/to/read') as file_1, \     open('/path/to/some/file/being/written', 'w') as file_2:    file_2.write(file_1.read())

(請參閱前面關于多行if-語句的讨論,以獲得關于這種多行with-語句縮進的進一步想法。) 

另一種類似情況是使用assert語句。 

確定在續行進行适當的縮進。

3.4 Should a line break before or after a binary operator? 在二進制運算符之前應該換行嗎?

幾十年來,推薦的風格是在二進制運算符之後中斷。但是這會影響可讀性,原因有二:操作符一般分布在螢幕上不同的列中,而且每個運算符被移到了操作數的上一行。下面例子這個情況就需要額外注意,哪些變量是相加的,哪些變量是相減的:

# 不推薦: 操作符離操作數太遠income = (gross_wages +          taxable_interest +          (dividends - qualified_dividends) -          ira_deduction -          student_loan_interest)

為了解決這種可讀性的問題,數學家和他們的出版商遵循了相反的約定。Donald Knuth在他的Computers and Typesetting系列中解釋了傳統規則:“盡管段落中的公式總是在二進制運算符和關系之後中斷,顯示出來的公式總是要在二進制運算符之前中斷”。 

遵循數學的傳統能産出更多可讀性高的代碼:

# 推薦:運算符和操作數很容易進行比對income = (gross_wages          + taxable_interest          + (dividends - qualified_dividends)          - ira_deduction          - student_loan_interest)

在Python代碼中,允許在二進制運算符之前或之後中斷,隻要本地的約定是一緻的。對于新代碼,建議使用Knuth的樣式。

3.5 Blank Lines 空行

頂層函數和類的定義,前後用兩個空行隔開。 

類裡的方法定義用一個空行隔開。 

相關的功能組可以用額外的空行(謹慎使用)隔開。一堆相關的單行代碼之間的空白行可以省略(例如,一組虛拟實作 dummy implementations)。 

在函數中使用空行來區分邏輯段(謹慎使用)。 

Python接受control-L(即^L)換頁符作為空格;許多工具把這些字元當作頁面分隔符,是以你可以在檔案中使用它們來分隔相關段落。請注意,一些編輯器和基于Web的代碼閱讀器可能無法識别control-L為換頁,将在其位置顯示另一個字形。

3.6 Source File Encoding 源檔案編碼

Python核心釋出版本中的代碼總是以UTF-8格式編碼(或者在Python2中用ASCII編碼)。 

使用ASCII(在Python2中)或UTF-8(在Python3中)編碼的檔案不應具有編碼聲明。 

在标準庫中,非預設的編碼應該隻用于測試,或者當一個注釋或者文檔字元串需要提及一個包含内ASCII字元編碼的作者名字的時候;否則,使用\x,\u,\U , 或者 \N 進行轉義來包含非ASCII字元。 

對于Python 3和更高版本,标準庫規定了以下政策(參見 PEP 3131):Python标準庫中的所有辨別符必須使用ASCII辨別符,并在可行的情況下使用英語單詞(在許多情況下,縮寫和技術術語是非英語的)。此外,字元串文字和注釋也必須是ASCII。唯一的例外是(a)測試非ASCII特征的測試用例,以及(b)作者的名稱。作者的名字如果不使用拉丁字母拼寫,必須提供一個拉丁字母的音譯。 

鼓勵具有全球閱聽人的開放源碼項目采取類似的政策。

3.7 Imports 導入

導入通常在分開的行,例如:

推薦: import osimport sys不推薦:  import sys, os

但是可以這樣:from subprocess import Popen, PIPE

導入總是位于檔案的頂部,在子產品注釋和文檔字元串之後,在子產品的全局變量與常量之前。 

導入應該按照以下順序分組:

标準庫導入

相關第三方庫導入

本地應用/庫特定導入

你應該在每一組導入之間加入空行。

推薦使用絕對路徑導入,如果導入系統沒有正确的配置(比如包裡的一個目錄在sys.path裡的路徑後),使用絕對路徑會更加可讀并且性能更好(至少能提供更好的錯誤資訊):

import mypkg.siblingfrom mypkg import siblingfrom mypkg.sibling import example

然而,顯示的指定相對導入路徑是使用絕對路徑的一個可接受的替代方案,特别是在處理使用絕對路徑導入不必要冗長的複雜包布局時:

from . import sibling from .sibling import example

标準庫要避免使用複雜的包引入結構,而總是使用絕對路徑。

不應該使用隐式相對路徑導入,并且在Python3中删除了它。

當從一個包含類的子產品中導入類時,常常這麼寫:

from myclass import MyClassfrom foo.bar.yourclass import YourClass

如果上述的寫法導緻名字的沖突,那麼這麼寫:

import myclassimport foo.bar.yourclass

然後使用“myclass.MyClass”和“foo.bar.yourclass.YourClass”。

避免通配符的導入(from import *),因為這樣做會不知道命名空間中存在哪些名字,會使得讀取接口和許多自動化工具之間産生混淆。對于通配符的導入,有一個防禦性的做法,即将内部接口重新釋出為公共API的一部分(例如,用可選加速器子產品的定義覆寫純Python實作的接口,以及重寫那些事先不知道的定義)。

當以這種方式重新釋出名稱時,以下關于公共和内部接口的準則仍然适用。

3.8 Module level dunder names 子產品級的“呆”名

像 __all__ ,  __author__,  __version__ 等這樣的子產品級“呆名“(也就是名字裡有兩個字首下劃線和兩個字尾下劃線),應該放在文檔字元串的後面,以及除from  __future__  之外的import表達式前面。Python要求将來在子產品中的導入,必須出現在除文檔字元串之外的其他代碼之前。 

比如:

"""This is the example module. This module does stuff. """from __future__ import barry_as_FLUFL__all__ = ['a', 'b', 'c']__version__ = '0.1'__author__ = 'Cardinal Biggles'import osimport sys

精選好文推薦:

我為什麼建議Python開發者将ES6作為第二語言

叨叨 Python 性能優化工具

Python快速安裝庫的靠譜辦法

自己的小霸王跑不起來?帶你薅一波kaggle的算力羊毛

你隻會用Python的pip安裝包?别錯過這些好用功能!

掃碼下圖關注我們不會讓你失望!

python 全部縮進一行_Python代碼這樣寫才規範優雅! (一)
python 全部縮進一行_Python代碼這樣寫才規範優雅! (一)

你點的每個在看,是我原創的動力!

繼續閱讀