創建成功的Python項目
創建一個成功的開源 Python 項目所涉及的并不僅僅是編寫有用的代碼,與其相關的還有社區的參與、越來越多的合作機會、技藝以及支持等。探索最佳的做法有助于你創建出自己的成功項目。
開源 Python 項目的生態系統豐富多樣,這使得您能夠站在巨人的肩膀上來開發下一個開源項目。此外,這意味著存在一系列的社區規范和最佳做法,通過遵守這些約定并把這些做法應用到項目中,你可以為自己的軟件贏得更廣范圍的采用。
本文涵蓋了一些在構建大型和小型的項目時都運作得很好的實踐做法,這些項目都已經贏得了廣泛的用戶群體。這里給出的這些建議的都是合理的、有其意義的,不過,因為結果可能會有所不同,所以不必把它們當成嚴格的教條來遵守。
首先我們來討論一下,解耦的過程如何能夠帶來一個更強健的社區,在編寫、維護和支持開源軟件等各方面都帶來更大的生產能力。
合作(collaboration)和互助(cooperation)的對比
在 DjangoCon 2011 大會期間,David Eaves 作了基調發言,雄辯地表達了這樣的想法,即盡管合作(collaboration)和互助(cooperation)有著類似的定義,但還是有著細微的差別:
“我認為,和作(collaboration)不同于互助(cooperation),其需要項目涉及到的各方通力來解決問題。”
Eaves 接著又給出了一整篇文章,專門說明 GitHub 如何成為革新開源的運作方式——特別是在社區管理方面的運作方式的推動力。在“How GitHub Saved OpenSource”這篇文章(參見參考資料)中,Eaves 說到:
“我相信,當捐獻者能夠以低交易成本的互助方式來參與,并且高交易成本的合作盡可能的少時, 開源項目的運作能達到最好。開源的高明之處就在于其不需要一個工作組來共同討論每個問題以及解決問題,而是恰恰相反。”
他接著談到了分支(forking)的價值所在,以及其如何通過在參與者之間啟用低成本的互助來降低合作的高成本,這些參與者能夠在無需批準的情況下推進項目。這種分支把需要的合作擱置起來,直到解決方案已經做好了合并的準備為止,如此來支持更快速的動態的實驗。
你可以以類似的方式來打造自己的項目,目標是相同的:在編寫、管理和支持項目的整個期間,增加低成本的互助,同時盡可能減少代價高昂的合作。
編寫
從一張白紙開始,創建一些新鮮的東西,制造一些有創意的東西——或僅僅是一些與現有的略不同的東西,沒有什么事情比得上啟動一個新的項目并和全世界分享你的努力成果讓人感覺更好的了。
與維護不同,在編寫代碼時,你是在創造新的東西而不是在修改或是修正已有的東西。編寫和構思一個項目除了是一門科學之外還是一種藝術形式,其他人會看到實現的情況并會對代碼的質量作出判斷,而你的名字將會永遠和它連在一起。
因此。了解工匠的心態以及據此來編寫軟件的方法是很重要的。編寫新的項目不僅僅是意味著生成代碼:項目的創建和構思包括了編寫有著精美風格的讓人樂于閱讀的代碼、在適當的時候為驗證項目中的功能創建測試代碼,以及制作詳盡的有幫助的文檔。
技藝
工藝(craft)一般是指藝術行業或是職業需要特殊的技能來手工制作一些東西,通常是小規模生產的物理器件。就軟件工匠關注的更多的是質量而非數量這一意義而言,你可以延伸這一定義,把它應用在軟件上。
對于工匠來說,產品具有吸引力而非只是功用是很重要的。具體來說,在軟件中,工匠要努力確保代碼的干凈和美觀、應用編程接口(API)的悅目,以及文檔和測試用例能夠給用戶帶來是在使用堅實的產品進行工作的這種感受。
在這種心態下工作,對于心靈來說是一種獎賞,也是在制作開源軟件時能感受到諸多享受的原因:你不再受困于回應最后期限、客戶以及其他的外部需求,而是按照自己的時間來,享受制作一些美好事物的樂趣。
代碼風格和規范檢查
Python 的增強建議(Python Enhancement Proposal,PEP)8(參見參考資料)是一個詳細的 Python 風格指南,你應該基于該指南來建立自己的 Python 項目(或至少是基于你的項目的風格指南)。不是非要教條地采用 PEP 8,不過你的工作成果越接近 PEP 8 規范,其他的 Python 開發者就越容易提交以標準的 Python 社區風格實現的整潔的補丁包。
除了風格的一致性之外,在捕捉諸如缺失導入和未定義變量一類的錯誤方面,代碼規范(linting)的概念也是很有作用的。除了風格檢查器會幫助你進行檢查,找出違背了默認規則或是自定義規則的代碼之外,現還有一些規范器(linter)或是一些工具,最常用到的一些實用程序是:
1. pyflakes
2. pylint
3. pep8
請參閱參考資料獲得到這些工具的鏈接。
無論你選擇遵從的是哪一種約定,如果這些約定偏離了 PEP 8 的話,我建議文檔化它們,以便讓那些想要為你的項目做貢獻的人了解你所采用的編碼風格,顯式的說明要好于隱含不語。
pyflakes 是一個特別有用的規范器,它很好地平衡了有用的功能、捕捉和標出錯誤這兩方面,不會過度地揪住微小的古怪做法不放。下面是一個在某個 Python 項目上使用 pyflakes 的示例會話:
$ pyflakes kaleo
kaleo/forms.py:1: 'form' imported but unused
kaleo/forms.py:4: undefined name 'forms'
kaleo/forms.py:6: undefined name 'forms'
立刻,該工具告訴了我有一個 import 的輸入錯誤,查看文件 kaleo/forms.py,我發現:
from django import form
class InviteForm (forms.Form):
email_address = forms.EmailField ()
從內容中可看出來,要把第 1 行改為 from django import forms。
測試
在項目中提供驗證代碼有效性的測試始終是一件好事,以此來防止回歸被忽視,以及在某些情況下作為一種文檔形式,通過閱讀其中的測試代碼可以讓其他人知道你的庫 API 是如何工作的。
話雖如此,但我不會根據項目是否包括測試用例或是完成這些測試的方式來判斷項目的完整性或可行性。測試用例的存在并不能保證代碼的質量,這可能是一個有爭議的觀點,但我相信,完全沒有測試比去測一些錯誤的東西要來得好一些。在編寫測試代碼時,考慮為每個測試單元給出各種輸入是一件很重要的事情。
文檔
不過,與測試不同的是,你可以根據項目文檔的質量和廣博性來判斷項目的質量和技藝水平。用與創作和維護代碼相同的方式來創作和維護穩定,編寫良好的并且是有深度的文檔會鼓勵捐獻者效仿你的做法,使你的項目變得更易于為用戶接受。
使用諸如 Sphinx 和 Read the Docs 一類的工具(參見參考資料),你可以發布及時更新的、外觀極為不錯的文檔。使用這些工具是一件簡單的事情,也就是寫一些文字內容并并推送提交。習慣于盡可能地使用 commit 來提交文檔的變更是很適當的一種做法。
維護
在 Python Package Index(PyPI)上發布了第一個版本,并通過各種 Tweet 消息和博客文章公布該版本的消息,開始有了一些使用者之后,你就需要在任何后續的創作活動中加入維護方面的考慮了。用戶會報告錯誤、要求添加功能、提一些文檔中沒有明顯涉及到問題,諸如此類等等。
有些事情你會選擇不去處理,給出一些權變措施;但其他的一些問題,你會打算或是修正文檔或是修正代碼。使用諸如 git 一類的分布式版本控制系統(distributed version control system,DVCS)并常常發布開發者包,這種做法可以大大簡化維護工作,使之變成一件不再是煩人的事情。
源控制
有許多可用的 DVCS,其中就包括了 git 和 mercurial(參見參考資料),無論你選擇的是哪一個控制系統,請確保它提供了源控制功能,這種功能賦予你這樣的能力,可以讓用戶分支你的項目,然后自己來解決其中的錯誤。
進行變更的速率取決于許多因素,一個關鍵的因素是目標受眾(例如,其他開發者、非技術型的最終用戶)。如果你的項目是針對開發者來編寫的,那么鼓勵通過拉請求(pull request)來報告錯誤或是請求功能之類的做法可以真正地做到降低維護者的負擔。這種做法還提升了社區的歸屬感,因為大家都把他們的捐獻合并到了將來的版本中。
開發構建
你會希望盡早地以及經常性地發布開發版本,在每次有一組附加的補丁包出來之后都會發布版本,如此多次。這會讓其他在工作中使用你的項目的開發者能夠更容易地針對項目中的最新更改來運行。越多的人在不同的情況下使用這些代碼,那么一旦到發布一個新的穩定版本的時候,該版本就會有越高的質量。
支持
支持是和維護相隨的,參與并構建一個由用戶和捐獻者組成的社區至關重要。賦予其他人通過支持來幫助你的權利,你就是在增強項目的全面合作因素,在項目的規模方面提供更好的伸縮性,以及自然而然地增加了解決用戶問題的做法。
為了達到該目的,請確保提供多種渠道來增加接觸的機會,讓用戶更加容易地與你接洽以及參與到項目中。可選的溝通渠道包括 IRC、郵件列表以及諸如 推ter 一類的社交媒體匯聚點。
IRC
在諸如 freenode 一類的 IRC 平臺上設置一個溝通頻道是一個好主意,我就為自己的項目設置了一個:nashvegas;除了我之外只有一個用戶,雖然這種情況很少有,但我的 IRC 客戶端還是悄無聲息地運行在后臺。當偶爾有用戶提問時,我能夠只花很少的交易成本就以一種比通過郵件要動態得多的方式來做出響應。
郵件列表
對于大多數的開源項目來說,有一個用于支持的郵件列表并在捐獻者之間討論開發進程是一種標準的做法。我的建議是,把支持放在一個郵件列表中,只有在內容已經變得太多,彼此影響到了各小組的討論的時候,才把它分成“用戶”列表和“開發”列表。
推ter
為項目開設一個 推ter 帳戶,大家可以在這里與你快速地討論工作。推ter 帳戶還是一個可以作為發布項目消息的好地方。
結束語
給 Python 社區中的開源軟件編寫并捐獻代碼是一種有趣且有益的體驗。在增加低成本互助機會的同時側重于減少高成本的合作,這種做法有助于項目與活躍的捐獻者一起成長。在開源領域,就你的項目來說,你有大把的自由來成為一個能工巧匠,充分利用這一點并享受它。把關注的重點放在一致的代碼風格、堅實的測試和編寫良好的文檔上,以此來提高項目被用戶和其他開發者采用的幾率。此外,要利用 DVCS,關注拉請求,經常性地發布開發版本。最后還有一點就是,你可以提供多種支持渠道,以及允許社區協助你提供這種支持,通過這些做法來進一步提升項目的采用率并促進項目的成長。
學習資料
1. 閱讀 Mark Pilgrim 的 Dive into Python,獲取關于該語言的一個介紹。
2. 欲了解更多關于打包 Python 項目方面的信息,可以讀一下 A guide to Python packaging(Patrick Altman,developerWorks,2011年 10 月)這篇文章。
3. 閱讀更多 David Eaves 的博客文章: Wikis and Open Source: Collaborative or Cooperative? 和 How GitHub Saved OpenSource.
4. 在潛心進行下一個 Python 項目之前,請確保已了解 PEP 8,Python 代碼的這一“官方”風格指南。
5. 瀏覽一下我的項目 nashvegas 的 GitHub 頁面,以此來做為一個使用 DVCS 的 Python 項目的例子。
6. 看一看 PyPI。
7. 了解更多關于分布式 Python 模塊方面的內容。
8. developerWorks 開源專區提供了豐富的關于開源工具和使用開源技術方面的信息。
9. 在 推ter 上關注 developerWorks。
10. 在 Easy and beautiful documentation with Sphinx (Alfredo Deza,developerWorks,2011年 11 月)一文中了解更多關于 Sphinx 的內容。
獲取產品和技術
1. 有許多可用的規范器,常見的選擇包括了 pyflakes、pylint,以及 Python 風格指南檢查器 pep8。
2. 在準備往項目中加入文檔的時候,一些在線的工具可把這一工作變得更容易一些。兩種這樣的工具選擇是 Sphinx and Read the Docs。
3. git 和 Mercurial 都是非常棒的 DVCS。
討論
1. 看看一些 developerWorks 博客文章,幫助在 developerWorks 社區中建立 Real world open source 組。
關于作者
Patrick Altman 是 Pinax 的一位核心開發者,其創建并為其他的許多開源項目貢獻了自己的力量。現在是 Engineering at Eldarion 的 VP。在這之前,他是 StudioNow 的首席軟件工程師(Principal Software Engineer),該公司后來被出售給了 AOL。目前他和妻子及三個孩子居住在田納西州的 Nashville。