原文連接:http://legacy.python.org/dev/peps/pep-0008/python
轉發連接:http://www.javashuo.com/article/p-ssraagam-mm.htmlgit
Tabs or Spaces 製表符仍是空格github
Should a line break before or after a binary operator 在二元運算符以前應該換行嗎Blank Lines 空行express
Imports 導入api
Module level dunder names 模塊級的呆名緩存
Descriptive Naming Styles 描述命名風格
Prescriptive Naming Conventions 約定俗成命名約定
Package and Module Names 包名和模塊名
Function and method arguments 函數和方法參數
Method Names and Instance Variables 方法名和實例變量
Designing for inheritance 繼承的設計
Public and internal interfaces 公共和內部的接口
Introduction 介紹
本文提供的Python代碼編碼規範基於Python主要發行版本的標準庫。Python的C語言實現的C代碼規範請查看相應的PEP指南1。
這篇文檔以及PEP 257(文檔字符串的規範)改編自Guido原始的《Python Style Guide》一文,同時添加了一些來自Barry的風格指南2。
這篇規範指南隨着時間的推移而逐漸演變,隨着語言自己的變化,過去的約定也被淘汰了。
許多項目有本身的編碼規範,在出現規範衝突時,項目自身的規範優先。
A Foolish Consistency is the Hobgoblin of Little Minds 盡信書,則不如無書
Guido的一條重要的看法是代碼閱讀比寫更加頻繁。這裏提供的指導原則主要用於提高代碼的可讀性,使得在大量的Python代碼中保持一致。就像PEP 20提到的,「Readability counts」。
這是一份關於一致性的風格指南。這份風格指南的風格一致性是很是重要的。更重要的是項目的風格一致性。在一個模塊或函數的風格一致性是最重要的。
然而,應該知道何時應該不一致,有時候編碼規範的建議並不適用。當存在模棱兩可的狀況時,使用本身的判斷。看看其餘的示例再決定哪種是最好的,不要羞於發問。
特別是不要爲了遵照PEP約定而破壞兼容性!
幾個很好的理由去忽略特定的規則:
1. 當遵循這份指南以後代碼的可讀性變差,甚至是遵循PEP規範的人也以爲可讀性差。
2. 與周圍的代碼保持一致(也可能出於歷史緣由),儘管這也是清理他人混亂(真正的Xtreme Programming風格)的一個機會。
3. 有問題的代碼出如今發現編碼規範以前,並且也沒有充足的理由去修改他們。
4. 當代碼須要兼容不支持編碼規範建議的老版本Python。
Code lay-out 代碼佈局
Indentation 縮進
每一級縮進使用4個空格。
續行應該與其包裹元素對齊,要麼使用圓括號、方括號和花括號內的隱式行鏈接來垂直對齊,要麼使用掛行縮進對齊3。當使用掛行縮進時,應該考慮到第一行不該該有參數,以及使用縮進以區分本身是續行。
推薦:
# 與左括號對齊
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沒有明確指明要如何區分i發的條件代碼和內嵌代碼。可以使用的選項包括但不限於下面幾種狀況:
# 沒有額外的縮進
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',
)
Tabs or Spaces?製表符仍是空格?
空格是首選的縮進方式。
製表符只能用於與一樣使用製表符縮進的代碼保持一致。
Python3不容許同時使用空格和製表符的縮進。
混合使用製表符和空格縮進的Python2代碼應該統一轉成空格。
當在命令行加入-t選項執行Python2時,它會發出關於非法混用製表符與空格的警告。當使用–tt時,這些警告會變成錯誤。強烈建議使用這樣的參數。
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語句。
確保在續行進行適當的縮進。
Should a line break before or after a binary operator? 在二元運算符以前應該換行嗎?
幾十年來,推薦的風格是在二元運算符以後中斷。可是這回影響可讀性,緣由有二:操做符通常分佈在屏幕上不一樣的列中,並且每一個運算符被移到了操做數的上一行。下面例子這個狀況就須要額外注意,那些變量是相加的,那些變量是相減的:
# 不推薦: 操做符離操做數太遠
income = (gross_wages +
taxable_interest +
(dividends - qualified_dividends) -
ira_deduction -
student_loan_interest)
# 推薦:運算符和操做數很容易進行匹配
income = (gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest)
Blank Lines 空行
頂層函數和類的定義,先後用兩個空行隔開。
類裏的方法定義用一個空行隔開。
相關的功能組能夠用額外的空行(謹慎使用)隔開。一堆相關的單行代碼之間的空白行能夠省略(例如,一組虛擬實現 dummy implementations)。
在函數中使用空行來區分邏輯段(謹慎使用)。
Python接受control-L(即^L)換頁符做爲空格;許多工具把這些字符看成頁面分隔符,因此你能夠在文件中使用它們來分隔相關段落。請注意,一些編輯器和基於Web的代碼閱讀器可能沒法識別control-L爲換頁,將在其位置顯示另外一個字形。
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)做者的名稱。做者的名字若是不使用拉丁字母拼寫,必須提供一個拉丁字母的音譯。
鼓勵具備全球受衆的開放源碼項目採起相似的政策。
Imports 導入
推薦: import os
import sys
不推薦: import sys, os
可是能夠這樣:
from subprocess import Popen, PIPE
1. 標準庫導入
2. 相關第三方庫導入
3. 本地應用/庫特定導入
你應該在每一組導入之間加入空行。
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
from . import sibling
from .sibling import example
from myclass import MyClass
from foo.bar.yourclass import YourClass
若是上述的寫法致使名字的衝突,那麼這麼寫:
import myclass
import foo.bar.yourclass
而後使用「myclass.MyClass」和「foo.bar.yourclass.YourClass」。
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 os
import sys
String Quotes 字符串引號
在Python中,單引號和雙引號字符串是相同的。PEP不會爲這個給出建議。選擇一條規則並堅持使用下去。當一個字符串中包含單引號或者雙引號字符的時候,使用和最外層不一樣的符號來避免使用反斜槓,從而提升可讀性。
對於三引號字符串,老是使用雙引號字符來與PEP 257中的文檔字符串約定保持一致。
Whitespace in Expressions and Statements 表達式和語句中的空格
Pet Peeves 不能忍受的事情
在下列狀況下,避免使用無關的空格:
Yes: spam(ham[1], {eggs: 2})
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
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]
不推薦:
ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]
Yes: spam(1)
No: spam (1)
Yes: dct['key'] = lst[index]
No: dct ['key'] = lst [index]
x = 1
y = 2
long_variable = 3
不推薦:
x = 1
y = 2
long_variable = 3
Other Recommendations 其餘建議
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
不推薦:
i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
def complex(real, imag=0.0):
return magic(r=real, i=imag)
不推薦:
def complex(real, imag = 0.0):
return magic(r = real, i = imag)
def munge(input: AnyStr): ...
def munge() -> AnyStr: ...
不推薦:
def munge(input:AnyStr): ...
def munge()->PosInt: ...
def munge(sep: AnyStr = None): ...
def munge(input: AnyStr, sep: AnyStr = None, limit=1000): ...
def munge(input: AnyStr=None): ...
def munge(input: AnyStr, limit = 1000): ...
if foo == 'blah':
do_blah_thing()
do_one()
do_two()
do_three()
if foo == 'blah': do_blah_thing()
do_one(); do_two(); do_three()
if foo == 'blah': do_blah_thing()
for x in lst: total += x
while t < 10: t = delay()
絕對別這樣:
if foo == 'blah': do_blah_thing()
else: do_non_blah_thing()
try: something()
finally: cleanup()
do_one(); do_two(); do_three(long, argument,
list, like, this)
if foo == 'blah': one(); two(); three()
Comments 註釋
與代碼相矛盾的註釋比沒有註釋還糟,當代碼更改時,優先更新對應的註釋!
註釋應該是完整的句子。若是一個註釋是一個短語或句子,它的第一個單詞應該大寫,除非它是以小寫字母開頭的標識符(永遠不要改變標識符的大小寫!)。
若是註釋很短,結尾的句號能夠省略。塊註釋通常由完整句子的一個或多個段落組成,而且每句話結束有個句號。
在句尾結束的時候應該使用兩個空格。
當用英文書寫時,遵循Strunk and White (譯註:《Strunk and White, The Elements of Style》)的書寫風格。
在非英語國家的Python程序員,請使用英文寫註釋,除非你120%的確信你的代碼不會被使用其餘語言的人閱讀。
Block Comments 塊註釋
塊註釋一般適用於跟隨它們的某些(或所有)代碼,並縮進到與代碼相同的級別。塊註釋的每一行開頭使用一個#和一個空格(除非塊註釋內部縮進文本)。
塊註釋內部的段落經過只有一個#的空行分隔。
Inline Comments 行內註釋
有節制地使用行內註釋。
行內註釋是與代碼語句同行的註釋。行內註釋和代碼至少要有兩個空格分隔。註釋由#和一個空格開始。
事實上,若是狀態明顯的話,行內註釋是沒必要要的,反而會分散注意力。好比說下面這樣就不須要:
x = x + 1 # Increment x
但有時,這樣作頗有用:
x = x + 1 # Compensate for border
Documentation Strings 文檔字符串
編寫好的文檔說明(也叫「docstrings」)的約定在PEP 257中永恆不變。
"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""
1對於單行的文檔說明,尾部的三引號應該和文檔在同一行。
Naming Conventions 命名規範
Python庫的命名規範很亂,歷來沒能作到徹底一致。可是目前有一些推薦的命名標準。新的模塊和包(包括第三方框架)應該用這套標準,但當一個已有庫採用了不一樣的風格,推薦保持內部一致性。
Overriding Principle 最重要的原則
那些暴露給用戶的API接口的命名,應該遵循反映使用場景而不是實現的原則。
Descriptive: Naming Styles 描述:命名風格
有許多不一樣的命名風格。這裏可以幫助你們識別正在使用什麼樣的命名風格,而不考慮他們爲何使用。
如下是常見的命名方式:
也有用惟一的短前綴把相關命名組織在一塊兒的方法。這在Python中不經常使用,但仍是提一下。好比,os.stat()函數中包含相似以st_mode,st_size,st_mtime這種傳統命名方式命名的變量。(這麼作是爲了與 POSIX 系統的調用一致,以幫助程序員熟悉它。)
X11庫的全部公共函數都加了前綴X。在Python裏面不必這麼作,由於屬性和方法在調用的時候都會用類名作前綴,函數名用模塊名作前綴。
另外,下面這種用前綴或結尾下劃線的特殊格式是被承認的(一般和一些約定相結合):
Prescriptive: Naming Conventions 約定俗成:命名約定
Names to Avoid 應避免的名字
永遠不要使用字母‘l’(小寫的L),‘O’(大寫的O),或者‘I’(大寫的I)做爲單字符變量名。
在有些字體裏,這些字符沒法和數字0和1區分,若是想用‘l’,用‘L’代替。
Package and Module Names 包名和模塊名
模塊應該用簡短全小寫的名字,若是爲了提高可讀性,下劃線也是能夠用的。Python包名也應該使用簡短全小寫的名字,但不建議用下劃線。
當使用C或者C++編寫了一個依賴於提供高級(更面向對象)接口的Python模塊的擴展模塊,這個C/C++模塊須要一個下劃線前綴(例如:_socket)
Class Names 類名
類名通常使用首字母大寫的約定。
在接口被文檔化而且主要被用於調用的狀況下,可使用函數的命名風格代替。
注意,對於內置的變量命名有一個單獨的約定:大部份內置變量是單個單詞(或者兩個單詞鏈接在一塊兒),首字母大寫的命名法只用於異常名或者內部的常量。
Exception Names 異常名
由於異常通常都是類,全部類的命名方法在這裏也適用。然而,你須要在異常名後面加上「Error」後綴(若是異常確實是一個錯誤)。
Global Variable Names 全局變量名
(咱們但願這一類變量只在模塊內部使用。)約定和函數命名規則同樣。
經過 from M import * 導入的模塊應該使用all機制去防止內部的接口對外暴露,或者使用在全局變量前加下劃線的方式(代表這些全局變量是模塊內非公有)。
Function Names 函數名
函數名應該小寫,若是想提升可讀性能夠用下劃線分隔。
大小寫混合僅在爲了兼容原來主要以大小寫混合風格的狀況下使用(好比 threading.py),保持向後兼容性。
Function and method arguments 函數和方法參數
始終要將 self 做爲實例方法的的第一個參數。
始終要將 cls 做爲類靜態方法的第一個參數。
若是函數的參數名和已有的關鍵詞衝突,在最後加單一下劃線比縮寫或隨意拼寫更好。所以 class_ 比 clss 更好。(也許最好用同義詞來避免這種衝突)
Method Names and Instance Variables 方法名和實例變量
遵循這樣的函數命名規則:使用下劃線分隔小寫單詞以提升可讀性。
在非共有方法和實例變量前使用單下劃線。
經過雙下劃線前綴觸發Python的命名轉換規則來避免和子類的命名衝突。
Python經過類名對這些命名進行轉換:若是類 Foo 有一個叫 __a 的成員變量, 它沒法經過 Foo.__a 訪問。(執着的用戶能夠經過 Foo._Foo__a 訪問。)通常來講,前綴雙下劃線用來避免類中的屬性命名與子類衝突的狀況。
注意:關於__names的用法存在爭論(見下文)。
Constants 常量
常量一般定義在模塊級,經過下劃線分隔的全大寫字母命名。例如: MAX_OVERFLOW 和 TOTAL。
Designing for inheritance 繼承的設計
始終要考慮到一個類的方法和實例變量(統稱:屬性)應該是共有仍是非共有。若是存在疑問,那就選非共有;由於將一個非共有變量轉爲共有比反過來更容易。
公共屬性是那些與類無關的客戶使用的屬性,並承諾避免向後不兼容的更改。非共有屬性是那些不打算讓第三方使用的屬性;你不須要承諾非共有屬性不會被修改或被刪除。
咱們不使用「私有(private)」這個說法,是由於在Python中目前尚未真正的私有屬性(爲了不大量沒必要要的常規工做)。
另外一種屬性做爲子類API的一部分(在其餘語言中一般被稱爲「protected」)。有些類是專爲繼承設計的,用來擴展或者修改類的一部分行爲。當設計這樣的類時,要謹慎決定哪些屬性時公開的,哪些是做爲子類的API,哪些只能在基類中使用。
貫徹這樣的思想,一下是一些讓代碼Pythonic的準則:
Public and internal interfaces 公共和內部的接口
任何向後兼容保證只適用於公共接口,所以,用戶清晰地區分公共接口和內部接口很是重要。
文檔化的接口被認爲是公開的,除非文檔明確聲明它們是臨時或內部接口,不受一般的向後兼容性保證。全部未記錄的接口都應該是內部的。
爲了更好地支持內省(introspection),模塊應該使用__all__屬性顯式地在它們的公共API中聲明名稱。將__all__設置爲空列表表示模塊沒有公共API。
即便經過__all__設置過,內部接口(包,模塊,類,方法,屬性或其餘名字)依然須要單個下劃線前綴。
若是一個命名空間(包,模塊,類)被認爲是內部的,那麼包含它的接口也應該被認爲是內部的。
導入的名稱應該始終被視做是一個實現的細節。其餘模塊必須不能間接訪問這樣的名稱,除非它是包含它的模塊中有明確的文檔說明的API,例如 os.path 或者是一個包裏從子模塊公開函數接口的 __init__ 模塊。
Programming Recommendations 編程建議
if foo is not None:
不推薦:
if not foo is None:
def f(x): return 2*x
不推薦:
f = lambda x: 2*x
第一個形式意味着生成的函數對象的名稱是「f」而不是泛型「< lambda >」。這在回溯和字符串顯示的時候更有用。賦值語句的使用消除了lambda表達式優於顯式def表達式的惟一優點(即lambda表達式能夠內嵌到更大的表達式中)。
try:
import platform_specific_module
except ImportError:
platform_specific_module = None
若是隻有一個except: 塊將會捕獲到SystemExit和KeyboardInterrupt異常,這樣會很難經過Control-C中斷程序,並且會掩蓋掉其餘問題。若是你想捕獲全部指示程序出錯的異常,使用 except Exception: (只有except等價於 except BaseException:)。
兩種狀況不該該只使用‘excpet’塊:
1. 若是異常處理的代碼會打印或者記錄log;至少讓用戶知道發生了一個錯誤。
2. 若是代碼須要作清理工做,使用 raise..try…finally 能很好處理這種狀況而且能讓異常繼續上浮。
1. 當給捕捉的異常綁定一個名字時,推薦使用在Python 2.6中加入的顯式命名綁定語法:
try:
process_data()
except Exception as exc:
raise DataProcessingFailedError(str(exc))
爲了不和原來基於逗號分隔的語法出現歧義,Python3只支持這一種語法。
try:
value = collection[key]
except KeyError:
return key_not_found(key)
else:
return handle_value(value)
不推薦:
try:
# Too broad!
return handle_value(collection[key])
except KeyError:
# Will also catch KeyError raised by handle_value()
return key_not_found(key)
with conn.begin_transaction():
do_stuff_in_transaction(conn)
不推薦:
with conn:
do_stuff_in_transaction(conn)
def foo(x):
if x >= 0:
return math.sqrt(x)
else:
return None
def bar(x):
if x < 0:
return None
return math.sqrt(x)
不推薦:
def foo(x):
if x >= 0:
return math.sqrt(x)
def bar(x):
if x < 0:
return
return math.sqrt(x)
推薦: if foo.startswith('bar'):
糟糕: if foo[:3] == 'bar':
正確: if isinstance(obj, int):
糟糕: if type(obj) is type(1):
當檢查一個對象是否爲string類型時,記住,它也有多是unicode string!在Python2中,str和unicode都有相同的基類:basestring,因此你能夠這樣:
if isinstance(obj, basestring):
注意,在Python3中,unicode和basestring都不存在了(只有str)而且bytes類型的對象再也不是string類型的一種(它是整數序列)
正確: if not seq:
if seq:
糟糕: if len(seq):
if not len(seq):
正確: if greeting:
糟糕: if greeting == True:
更糟: if greeting is True:
Function Annotations 功能註釋
隨着PEP 484的引入,功能型註釋的風格規範有些變化。
# type: ignore
這會告訴檢查器忽略全部的註釋。(在 PEP 484中能夠找到從類型檢查器禁用投訴的更細粒度的方法。)
參考
1. PEP 7, Style Guide for C Code, van Rossum ↩
2. Barry’s GNU Mailman style guide http://barry.warsaw.us/software/STYLEGUIDE.txt ↩
3. 掛行縮進是一種類型設置樣式,其中除第一行以外,段落中的全部行都縮進。在Python中,這個術語是用來描述一種風格:在被括號括起來的語句中,左括號是這一行最後一個非空格字符,隨後括號內的內容每一行進行縮進,直到遇到右括號。 ↩
4. Donald Knuth’s The TeXBook, pages 195 and 196 ↩
5. http://www.wikipedia.com/wiki/CamelCase ↩
6. Typeshed repo https://github.com/python/typeshed ↩
7. Suggested syntax for Python 2.7 and straddling code https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code ↩