Python編程風(fēng)格指南_第1頁
Python編程風(fēng)格指南_第2頁
Python編程風(fēng)格指南_第3頁
Python編程風(fēng)格指南_第4頁
Python編程風(fēng)格指南_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、目錄Python編程風(fēng)格規(guī)范1分號1行長度1括號1縮進(jìn)2空行2空格2Python 解釋器3注釋4類5塊注釋和行注釋6類6字符串7TODO 注釋7導(dǎo)入格式8語句8訪問控制9命名9Main10Python編程風(fēng)格規(guī)范分號不要在行尾加分號, 也不要用分號將兩條命令放在同一行.行長度 每行不超過80 個字符例外: 如果使用Python 2.4 或更早的版本, 導(dǎo)入模塊的行可能多于80 個字符.Python 會將圓括號, 中括號和花括號中的行隱式的連接起來, 你可以利用這個特點(diǎn). 如果需要, 你可以在表達(dá)式外圍增加一對額外的圓括號.Yes: foo_bar(self, width, height, co

2、lor='black', design=None, x='foo',emphasis=None, highlight=0)if (width = 0 and height = 0 andcolor = 'red' and emphasis = 'strong'):如果一個文本字符串在一行放不下, 可以使用圓括號來實(shí)現(xiàn)隱式行連接:x = ('This will build a very long long ''long long long long long long string')注意上面例子中的

3、元素縮進(jìn); 你可以在本文的 縮進(jìn) 部分找到解釋.括號寧缺毋濫的使用括號除非是用于實(shí)現(xiàn)行連接, 否則不要在返回語句或條件語句中使用括號. 不過在元組兩邊使用括號是可以的.Yes: if foo:bar()while x:x = bar()if x and y:bar()if not x:4bar()return foofor (x, y) in dict.items(): .No: if (x):bar()if not(x):bar()return (foo)縮進(jìn)用 4 個空格來縮進(jìn)代碼絕對不要用tab, 也不要tab 和空格混用. 對于行連接的情況, 你應(yīng)該要么垂直對齊換行的元素(見 行長度

4、部分的示例), 或者使用4 空格的懸掛式縮進(jìn)(這時第一行不應(yīng)該有參數(shù)):Yes: # Aligned with opening delimiterfoo = long_function_name(var_one, var_two,var_three, var_four)# 4-space hanging indent; nothing on first linefoo = long_function_name(var_one, var_two, var_three,var_four)No: # Stuff on first line forbiddenfoo = long_function_n

5、ame(var_one, var_two,var_three, var_four)# 2-space hanging indent forbiddenfoo = long_function_name(var_one, var_two, var_three,var_four)空行頂級定義之間空兩行, 方法定義之間空一行頂級定義之間空兩行, 比如函數(shù)或者類定義. 方法定義, 類定義與第一個方法之間, 都應(yīng)該空一行. 函數(shù)或方法中, 某些地方要是你覺得合適, 就空一行.空格按照標(biāo)準(zhǔn)的排版規(guī)范來使用標(biāo)點(diǎn)兩邊的空格1. 括號內(nèi)不要有空格.Yes: spam(ham1, eggs: 2, )No: spa

6、m( ham 1 , eggs: 2 , )2. 不要在逗號, 分號, 冒號前面加空格, 但應(yīng)該在它們后面加(除了在行尾).Yes: if x = 4:print x, yx, y = y, xNo: if x = 4 :print x , yx , y = y , x3. 參數(shù)列表, 索引或切片的左括號前不應(yīng)加空格.Yes: spam(1)Yes: spam (1)Yes: dict'key' = listindexNo: dict 'key' = list index4. 在二元操作符兩邊都加上一個空格, 比如賦值(=), 比較(=, <, >,

7、 !=, <>, <=, >=, in, notin, is, is not), 布爾(and, or, not). 至于算術(shù)操作符兩邊的空格該如何使用, 需要你自己好好判斷. 不過兩側(cè)務(wù)必要保持一致.Yes: x = 1No: x<15. 當(dāng)=用于指示關(guān)鍵字參數(shù)或默認(rèn)參數(shù)值時, 不要在其兩側(cè)使用空格.Yes: def complex(real, imag=0.0): return magic(r=real, i=imag)No: def complex(real, imag = 0.0): return magic(r = real, i = imag)6. 不

8、要用空格來垂直對齊多行間的標(biāo)記, 因?yàn)檫@會成為維護(hù)的負(fù)擔(dān)(適用于:, #, =等):Yes:foo = 1000 # commentlong_name = 2 # comment that should not be aligneddictionary = 6"foo": 1,"long_name": 2,No:foo = 1000 # commentlong_name = 2 # comment that should not be aligneddictionary = "foo" : 1,"long_name"

9、;: 2,Python 解釋器每個模塊都應(yīng)該以#!/usr/bin/env python<version>開頭模塊應(yīng)該以一個構(gòu)造行開始, 以指定執(zhí)行這個程序用到的Python 解釋器:#!/usr/bin/env python2.4總是使用最特化的版本, 例如, 使用/usr/bin/python2.4, 而不是 /usr/bin/python2. 這樣,當(dāng)升級到不同的Python 版本時, 能輕松找到依賴關(guān)系, 同時也避免了使用時的迷惑. 例如,/usr/bin/python2 是表示/usr/bin/python2.0.1 還是/usr/bin/python2.3.0?注釋確保

10、對模塊, 函數(shù), 方法和行內(nèi)注釋使用正確的風(fēng)格文檔字符串Python 有一種獨(dú)一無二的的注釋方式: 使用文檔字符串. 文檔字符串是包, 模塊, 類或函數(shù)里的第一個語句. 這些字符串可以通過對象的_doc_成員被自動提取, 并且被pydoc 所用. (你可以在你的模塊上運(yùn)行pydoc 試一把, 看看它長什么樣). 我們對文檔字符串的慣例是使用三重雙引號. 一個文檔字符串應(yīng)該這樣組織: 首先是一行以句號, 問號或驚嘆號結(jié)尾的概述. 接著是一個空行. 接著是文檔字符串剩下的部分, 它應(yīng)該與文檔字符串的第一行的第一個引號對齊. 下面有更多文檔字符串的格式化規(guī)范.模塊每個文件應(yīng)該包含下列項(xiàng), 依次是:1

11、. 版權(quán)聲明(例如, Copyright 2008 Google Inc.)2. 一個許可樣板. 根據(jù)項(xiàng)目使用的許可(例如, Apache 2.0, BSD, LGPL, GPL), 選擇合適的樣板3. 作者聲明, 標(biāo)識文件的原作者.函數(shù)和方法如果不是既顯然又簡短, 任何函數(shù)或方法都需要一個文檔字符串. 而且, 任何外部可訪問的函數(shù)或方法, 不管多短多簡單, 都需要文檔字符串. 文檔字符串應(yīng)該包含函數(shù)做什么, 以及輸入和輸出的詳細(xì)描述. 通常, 不應(yīng)該描述”怎么做”, 除非是一些復(fù)雜的算法. 對于技巧性的代碼, 塊注釋或者行內(nèi)注釋是最重要的. 文檔字符串應(yīng)該提供足夠的信息, 當(dāng)別人編寫代碼調(diào)用

12、該函數(shù)時, 他不需要看一行代碼, 只要看文檔字符串就可以了. 應(yīng)該給參數(shù)單獨(dú)寫文檔. 在冒號后跟上解釋, 而且應(yīng)該用統(tǒng)一的懸掛式2 或4空格縮進(jìn). 文檔字符串應(yīng)該在需要特定類型的地方指定期望的類型. “Raise:”部分應(yīng)該列出該函數(shù)可能觸發(fā)的所有異常. 生成器函數(shù)的文檔字符串應(yīng)該用”Yields:”而非”Returns:”.def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):"""Fetches rows from a Bigtable.Retrieves rows pertai

13、ning to the given keys from the Table instancerepresented by big_table. Silly things may happen ifother_silly_variable is not None.Args:big_table: An open Bigtable Table instance.keys: A sequence of strings representing the key of each table rowto fetch.other_silly_variable: Another optional variabl

14、e, that has a muchlonger name than the other args, and which does nothing.Returns:A dict mapping keys to the corresponding table row datafetched. Each row is represented as a tuple of strings. Forexample:'Serak': ('Rigel VII', 'Preparer'),'Zim': ('Irk', 'I

15、nvader'),'Lrrr': ('Omicron Persei 8', 'Emperor')If a key from the keys argument is missing from the dictionary,then that row was not found in the table.Raises:IOError: An error occurred accessing the bigtable.Table object."""pass類類應(yīng)該在其定義下有一個用于描述該類的文檔字符串. 如果

16、你的類有公共屬性(Attributes), 那么文檔中應(yīng)該有一個屬性(Attributes)段. 并且應(yīng)該遵守和函數(shù)參數(shù)相同的格式.class SampleClass(object):"""Summary of class here.Longer class information.Longer class information.Attributes:likes_spam: A boolean indicating if we like SPAM or not.eggs: An integer count of the eggs we have laid.&qu

17、ot;""def _init_(self, likes_spam=False):"""Inits SampleClass with blah."""self.likes_spam = likes_spamself.eggs = 0def public_method(self):"""Performs operation blah."""塊注釋和行注釋最需要寫注釋的是代碼中那些技巧性的部分. 如果你在下次代碼走查的時候必須解釋一下, 那么你應(yīng)該現(xiàn)在就給它寫注

18、釋. 對于復(fù)雜的操作, 應(yīng)該在其操作開始前寫上若干行注釋. 對于不是一目了然的代碼, 應(yīng)在其行尾添加注釋.# We use a weighted dictionary search to find out where i is in# the array. We extrapolate position based on the largest num# in the array and the array size and then do binary search to# get the exact number.if i & (i-1) = 0: # true iff i is

19、a power of 2為了提高可讀性, 注釋應(yīng)該至少離開代碼2 個空格.另一方面, 絕不要描述代碼. 假設(shè)閱讀代碼的人比你更懂Python, 他只是不知道你的代碼要做什么.# BAD COMMENT: Now go through the b array and make sure whenever i occurs# the next element is i+1類如果一個類不繼承自其它類, 就顯式的從object 繼承. 嵌套類也一樣.No: class SampleClass:passclass OuterClass:class InnerClass:passYes: class Sa

20、mpleClass(object):passclass OuterClass(object):class InnerClass(object):passclass ChildClass(ParentClass):"""Explicitly inherits from another class already."""繼承自 object 是為了使屬性(properties)正常工作, 并且這樣可以保護(hù)你的代碼, 使其不受Python 3000 的一個特殊的潛在不兼容性影響. 這樣做也定義了一些特殊的方法, 這些方法實(shí)現(xiàn)了對象的默認(rèn)語義

21、, 包括 _new_, _init_, _delattr_, _getattribute_,_setattr_, _hash_, _repr_, and _str_ .字符串用%操作符格式化字符串, 即使參數(shù)都是字符串. 不過也不能一概而論, 你需要在+和%之間好好判定.No: x = '%s%s' % (a, b) # use + in this casex = imperative + ', ' + expletive + '!'x = 'name: ' + name + ' score: ' + str(n)

22、Yes: x = a + bx = '%s, %s!' % (imperative, expletive)x = 'name: %s; score: %d' % (name, n)避免在循環(huán)中用+和+=操作符來累加字符串. 由于字符串是不可變的, 這樣做會創(chuàng)建不必要的臨時對象, 并且導(dǎo)致二次方而不是線性的運(yùn)行時間. 作為替代方案, 你可以將每個子串加入列表, 然后在循環(huán)結(jié)束后用 .join 連接列表. (也可以將每個子串寫入一個cStringIO.StringIO 緩存中.)No: employee_table = '<table>'

23、for last_name, first_name in employee_list:employee_table += '<tr><td>%s, %s</td></tr>' % (last_name, first_name)employee_table += '</table>'Yes: items = '<table>'for last_name, first_name in employee_list:items.append('<tr><td

24、>%s, %s</td></tr>' % (last_name, first_name)items.append('</table>')employee_table = ''.join(items)為多行字符串使用三重雙引號而非三重單引號. 不過要注意, 通常用隱式行連接更清晰, 因?yàn)槎嘈凶址c程序其他部分的縮進(jìn)方式不一致.No:print """This is pretty ugly.Don't do this."""Yes:print (&

25、quot;This is much nicer.n""Do it this way.n")TODO 注釋為臨時代碼使用TODO 注釋, 它是一種短期解決方案. TODO 注釋應(yīng)該在所有開頭處包含”TODO”字符串, 緊跟著是用括號括起來的你的名字,email 地址或其它標(biāo)識符. 然后是一個可選的冒號. 接著必須有一行注釋, 解釋要做什么. 主要目的是為了有一個統(tǒng)一的TODO 格式, 這樣添加注釋的人就可以搜索到(并可以按需提供更多細(xì)節(jié)). 寫了TODO 注釋并不保證寫的人會親自解決問題.# TODO(kl): Drop the use of "has_k

26、ey".# TODO(Zeke) change this to use relations.如果你的TODO 是”將來做某事”的形式, 那么請確保你包含了一個指定的日期(“2009 年11 月解決”)或者一個特定的事件(“等到所有的客戶都可以處理XML 請求就移除這些代碼”).導(dǎo)入格式每個導(dǎo)入應(yīng)該獨(dú)占一行Yes: import osimport sysNo: import os, sys導(dǎo)入總應(yīng)該放在文件頂部, 位于模塊注釋和文檔字符串之后, 模塊全局變量和常量之前. 導(dǎo)入應(yīng)該按照從最通用到最不通用的順序分組:1. 標(biāo)準(zhǔn)庫導(dǎo)入2. 第三方庫導(dǎo)入3. 應(yīng)用程序指定導(dǎo)入每種分組中, 應(yīng)該

27、根據(jù)每個模塊的完整包路徑按字典序排序, 忽略大小寫.import foofrom foo import barfrom foo.bar import bazfrom foo.bar import Quuxfrom Foob import ar語句通常每個語句應(yīng)該獨(dú)占一行不過, 如果測試結(jié)果與測試語句在一行放得下, 你也可以將它們放在同一行. 如果是if 語句,只有在沒有else 時才能這樣做. 特別地, 絕不要對 try/except 這樣做, 因?yàn)閠ry 和except不能放在同一行.Yes:if foo: bar(foo)No:if foo: bar(foo)else: baz(foo)t

28、ry: bar(foo)except ValueError: baz(foo)try: bar(foo)except ValueError: baz(foo)訪問控制在 Python 中, 對于瑣碎又不太重要的訪問函數(shù), 你應(yīng)該直接使用公有變量來取代它們,這樣可以避免額外的函數(shù)調(diào)用開銷. 當(dāng)添加更多功能時, 你可以用屬性(property)來保持語法的一致性.(譯者注: 重視封裝的面向?qū)ο蟪绦騿T看到這個可能會很反感, 因?yàn)樗麄円恢北唤逃? 所有成員變量都必須是私有的! 其實(shí), 那真的是有點(diǎn)麻煩啊. 試著去接受Pythonic 哲學(xué)吧)另一方面, 如果訪問更復(fù)雜, 或者變量的訪問開銷很顯著, 那么你應(yīng)該使用像get_foo() 和set_foo() 這樣的函數(shù)調(diào)用. 如果之前的代碼行為允許通過屬性(property)訪問 , 那么就不要將新的訪問函數(shù)與屬性綁定. 這樣, 任何試圖通過老方法訪問變量的代碼就沒法運(yùn)行, 使用者也就會意識到復(fù)雜性發(fā)生了變化.

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論