用 Eclipse 和 Ant 進行 Python 開發
用 Eclipse IDE 和 Apache Ant 構建工具進行 Python 開發
|
|
級別: 初級
Ron Smith
, 負責人
2004 年 6 月 01 日
Python 是一種非常靈活強大的動態腳本編程語言,具有完整的面向對象特性。眾多的支持者指出,Python 語言與其他語言相比能更快更有效地表達出他們的意圖。但是從 Java 技術? 或 Microsoft? .NET 剛剛轉到 Python 的人會發現,功能豐富而精致的 IDE 和開發工具都不見了。那些開發人員可以從他們熟悉的 Java 開發工具中找到解決方案。本文著重介紹了如何使用基于 Java 技術的流行開發工具 Eclipse 和 Ant 進行 Python 開發。
簡介
多年以來, Java 語言和 Python 陣營之間一直存在大量的異花授粉現象。在這方面作出突出表率的可能是 Jython。這是一個純粹用 Java 實現的 Python 運行時環境。按照這一說法,您將研究如何用 Eclipse IDE 和 Ant 構建與部署工具實現 Python 開發。Eclipse 和 Ant 是非常流行的工具,它們特性豐富、可擴展性強、而且開放源代碼;Python 也具有相同的品質。PyDev 和 PyAntTasks 分別是 Eclipse 和 Ant 的擴展,有了它們就可能用這些 Java 工具開發 Python。本文從下載安裝所需的工具與擴展開始講起。為了解釋如何在 Python 開發中使用 Eclipse 和 Ant,我將用實際的 Python 代碼例子讀取 RSS 資源。
本文不會涉及 Eclipse、Ant、Python 的細節。有關這些話題的深入討論,請參閱 參考資料 一節中的鏈接。
Python 支持情況
本文用到的軟件都在 CPython 2.3 下測試過。除了幾個異常情況之外,應該也能在 Jython 中運行。特別需要指出,PyDev 調試器目前不支持 Jython。另一個區別是通過 Jython 執行的腳本在從 PyDev 中運行之后就轉入交互模式,這樣就必須手動殺死。PyDev 編輯器與 Jython 的源代碼兼容,Python Ant 任務除 py-doc 任務之外也和 Jython 兼容。
使用 Eclipse 進行 Python 開發
Eclipse 概述
Eclipse 是一個 Java 技術集成開發環境,由 IBM 開發,并開放其源代碼。它是 IBM 商業軟件 WebSphere Application Development 環境以及其他多種工具的基礎。Eclipse 的開發社區非常活躍,他們不僅開發 Eclipse 本身,還開發大量的插件供 Eclipse 使用。有關 Eclispe 和 Eclipse 插件的 Web 站點,請參閱 參考資料 一節中的鏈接。盡管從傳統上講 Eclipse 是一種 Java 開發工具,但是一些插件的存在使得在 Eclipse 中開發其他語言的程序成為可能,如 C/C++、Python 和 Perl。
在 Eclipse 中,源代碼被組織到項目(project)中。項目可以加載、卸載和導入。Eclipse 用戶界面的結構劃分為視圖(View)與編輯器(Editor)。視圖與編輯器的例子包括:源代碼大綱視圖、Java 源代碼編輯器、Python 源代碼編輯器和文件系統導航視圖。Eclipse 用戶界面中最關鍵的隱含概念就是 視角(perspective)。視角是通常在執行某種類型活動時一起使用的一組視圖。Eclipse 中的標準視角包括:Debug、Java Browsing、Java、Java Type Hierarchy、Plug-in Development、CVS Repository Exploring、Resource 和 Install/Update。目前還不存在單獨的 Python 視角。在進行 Python 開發時,我通常使用 Resource 視角和 Debug 視角。
安裝 PyDev
首先,從 Eclipse Web 站點上下載 Eclipse(請參閱 參考資料 一節中的鏈接),并根據您的平臺,按照下面的安裝指南安裝 Eclipse:
Eclipse 的更新機制使 PyDev 插件的安裝更加容易。從 Eclipse 中選擇 Help > Software Updates > Update Manager,啟動 Install/Update 視角。在左下角的 Feature Updates 視圖中,將 PyDev 插件更新站點作為新的 Site Bookmark 添加到“Sites to Visit”文件夾下。Eclipse 的 PyDev 更新站點 URL 為 http://pydev.sf.net/updates/。現在,Feature Updates 編輯器中應該顯示出“PyDev”這一特性。在 Feature Updates 編輯器中,展開 PyDev > Other,選擇其中顯示的 PyDev 特性(至少應該是 0.4.1)。然后選擇 “Install Now”安裝該特性。Eclipse 將下載 PyDev 插件,并將其安裝到 Eclipse 中。
導入樣例項目
為訪問本項目中使用的樣例代碼,可先下載 zip 文件(請參閱 參考資料一節),在文件系統中展開該 zip 文件,然后將其中的項目導入 Eclipse。導入項目的方法是先切換到 Resource 視角,選擇 File > Import,再選擇“Existing Project into Workspace”,然后選擇您展開 zip 文件的位置。這時,Navigator 視圖中應該出現 feedParserTest 項目。
樣例項目中已經包含了 Fead Parser 通用資源解析庫,該庫按 Python 開放源代碼許可協議發布。有關 Feed Parser 項目 Web 網站的鏈接,請參閱 參考資料 一節。
PyDev 漫游
現在開始學習如何通過已導入的項目了解 PyDev 的特性。PyDev 正處于開發過程中,但已經是非常高效的 Python 開發環境。現在的 PyDev 主要包括以下特性:
- 包含 Python 語法高亮顯示特性的 Python 編輯器。
- 進行 Python 語法分析,并在 Python 編輯器和 Tasks 視圖中高亮顯示錯誤。
- 可將制表符轉換成空格的選項。
- Outline 視圖顯示導入的庫、類以及函數。
- 終端視圖中的 Python 堆棧跟蹤信息可超鏈接到源代碼中。
- 源代碼內部的超鏈接;同一模塊內的導入和函數調用可通過超鏈接進行導航。
- 從 Navigator 視圖中運行 Python 腳本的能力。
- 調試器支持斷點、代碼單步執行以及顯示變量的值。
PyDev 選項窗口
通過 Window > Preferences,并選擇 PyDev(請參閱圖 1),便可訪問 PyDev 選項。第一組選項可以改變 PyDev 在源代碼中處理制表符的方式,還可以改變語法元素的顏色。
圖 1. PyDev 選項窗口
設置 Python 解釋器
PyDev Debug 選項可以選擇 Python 解釋器,供執行 Python 代碼時使用。如果 PyDev 無法找到 Python 解釋器,或者想使用別的解釋器,可在此設置(請參閱圖 2)。
圖 2. PyDev Debug 選項
處理源代碼
我的大部分 Python 工作都是在 Resource 視角中完成的。使用方法是先切換到 Resource 視角,然后在左上角的 Navigator 視圖中雙擊 feedParserTest/src/feedparserTest/FeedparserTest.py 文件。Python 編輯器打開該文件,對 Python 語法進行解析,完成設置顏色和語法檢查的工作(請參閱圖 3)。
圖 3. Python 編輯器
如果源代碼中有任何錯誤,則顯示在右下角的 Tasks 視圖中顯示出來。雙擊 Tasks 視圖中的錯誤,便可找到那條討厭的代碼行。
Outline 視圖在左下角,其中用一種便于瀏覽的結構顯示出當前正在編輯的文件。導入的庫、類、函數全都顯示出來,通過雙擊 Outline 視圖中的項目,便可以實現導航。PyDev 在編輯 Python 文件的過程中對齊進行預先解析的工作,同時更新 Outline 視圖,執行語法檢查,并用不同顏色顯示語法元素。
編輯器的特性
PyDev 0.4 版在 Python 源代碼編輯器中為函數和導入庫加入了超鏈接的特性。如果在越過某項導入或函數調用(必須在 PYTHONPATH
目錄中)的同時按下 Control 鍵,PyDev 就能顯示出一個超鏈接,這樣您可以在導入庫或函數的源代碼之間導航。請注意,為了在您自己的源代碼中跨模塊使用該特性(從一個模塊鏈接到另一個模塊),必須修改 PYTHONPATH
環境變量,在其中加入這些模塊,這樣 PyDev 就可以找到它們了。
人們已經開始將一些優異的源代碼編輯特性加入最新版本的 PyDev 中,其中就包括代碼塊注釋與取消注釋,以及代碼左右移位(請參閱圖 4)。
圖 4. PyDev 編輯器的其他特性
運行 Python 腳本
如果不能執行代碼,那么 IDE 也不是太有用。為執行 Python 代碼,可從 Navigator 視圖中選擇 feedparser.py 文件,用右鍵點擊,然后選擇 Python > Run。隨后會顯示 Python 的啟動配置窗口(請參閱圖 5)。
圖 5. Python 啟動配置
Python 啟動配置窗口中可以定義腳本執行的當前目錄,傳遞給腳本的參數,以及用哪一個 Python 解釋器運行腳本。feedparser.py 以一個 RSS URL 作為參數,所以可在參數字段中填入 URL,如 http://www.ibm.com/developerworks/news/dw_dwtp.rss。其余的缺省定義就可以了,所以單擊 Run。
腳本執行時輸出信息顯示在 Console 窗口中。如果有錯誤出現,Console 窗口中將顯示堆棧跟蹤信息,其中的每一行都可以通過超鏈接找到 Python 源代碼。
Python 調試器
Python 調試器是最近才加入 PyDev 插件中的。要使用調試器,可在 Python 編輯器中想中斷的代碼行的左側點擊,設置斷點。在圖 6 中,我在 feedparser.py 的 1830 行處設置了斷點。然后在 Navigator 視圖中選擇這個 Python 模塊,點擊右鍵,選擇“Python > Debug...”。這時將顯示與前面相似的一個啟動配置窗口。點擊 Debug 進入 Debug 視角,同時啟動調試器。
圖 6. Python 調試器
左上角的 Debug 視圖顯示當前正在執行的進程和線程,右上角的 Variables 視圖顯示當前運行域中的所有變量,Python 編輯器會顯示調試器目前停在哪條語句上,同時所有的輸出信息都顯示與 Console 視圖中。調試器可以通過 Debug 視圖底部的按鈕或 Run 菜單進行控制。
其他 Eclipse 特性
Eclipse 及其插件還具備很多其他的特性,可應用于 Python 開發中,如 XML 編輯器、UML 編輯器(不過大多數是以 Java 代碼為中心),還有資源控制方面的插件。目前 Eclipse 插件站點上列出的插件幾乎有 500 個(請參閱 參考資料 一節中的相關鏈接)。我將著重介紹一個對很多 Python 開發人員都特別有用的插件:Eclipse 發行版中已經包括的 CVS 插件,不過不會討論細節內容。
Eclipse 中包括特性豐富的集成 CVS:
- 支持 SSH、pserver、ext 等連接方法。
- 基本 CVS 命令的支持:檢出項目、提交變更、更新、向.cvsignore 中增加文件或模式等等。
- 文件合并查看。
- 在源代碼控制中實現對文件不同之處的比較。
- 項目同步,并用資料庫顯示出刪除和新增的內容。
還可以通過提供其他插件來支持其他源代碼控制系統,如 ClearCase、Subversion、Visual SourceSafe 等。
在 Eclipse 中使用 Python 的交互式 shell
Python 解釋器支持 Python 代碼的交互式執行。這種方式對于調試一段代碼是非常有用的,因為不用把代碼放進 Python 腳本中并執行腳本了。同時,Python 解釋器的交互模式可以很容易地集成到 Eclipse 中。
要增加對 Python 交互式執行的支持,可通過 Run > External Tools > External Tools 增加一個 External Tool 啟動程序。這時將打開 External Tool 啟動程序配置窗口。在 Configurations 列表中選擇“Program”,然后點擊“New”創建一個新的配置。將該配置命名為諸如 "pythonInteractive" 之類,然后設置 Location,令其指向您的 Python 解釋器,接著,將 "-i" 作為唯一的參數傳遞進來(請參閱圖 7)。
在 Common 選項卡下,選中復選框,使該配置在 External Tools 收藏夾菜單中顯示出來。
圖 7. Python 交互方式配置
要運行剛剛在 Eclipse 中創建的啟動器,可選擇 Run > External Tools > pythonInterpreter。Python 解釋器的輸出顯示在 Console 視圖中。Console 中可輸入 Python 命令并執行,就像從命令行中執行 Python 一樣。為導入并在交互模式下使用模塊,您需要將模塊的位置增加到 PYTHONPATH
環境變量中。
在 Eclipse Console 中執行 Python 與用命令行執行的不同之處在于,無法啟用命令歷史特性(通過向上和向下的方向鍵實現),因為 Eclipse Console 會自己解釋這些鍵。
在 Python 開發中使用 Ant
Python 會在它需要的時候自動編譯模塊。這意味著 Python 開發人員通常不必顯式地對模塊進行編輯。即便如此,有時候手工編譯 Python 代碼還是很有用的,同時,構建和部署過程中還有很多其他方面的內容可以自動化實現。這也正是構建工具的用武之地。
我將著重介紹來自 Java 編程世界中的 Apache Ant,這個工具可大量應用在 Python 開發中。Apache Ant 是 Java 編程領域內事實上的標準構建工具。它更加輕便,與 Java 技術結合得更好,可用于替代其他的構建工具。Ant 可以在支持 Java 編程語言的任何一種平臺上運行。盡管我們需要的大多數構建特性 Ant 都已經提供了,但如果要將 Ant 用做 Python 構建工具,還是需要有一些關鍵的與 Python 相關的特性。我已經開發了若干定制的 Ant 插件(用 Ant 的行話講叫做 task),可提供構建 Python 時需要的特定于 Python 的特性。
Ant 用 XML 作為描述構建的格式。build 文件組織為需要執行的目標。每一個目標都可能依賴于其他的目標。Ant 將根據您所請求執行的目標,以及一組依賴目標,來執行任何需要的目標。每一個目標都可能包含任意數量的 Ant 任務,而由 Ant 任務實際執行目標的工作。Ant 有很多內置的任務,可以完成諸如編譯 Java 代碼、生成文檔、操縱文件和目錄,同時第三方又提供了很多附加的任務。
安裝 Python Ant 庫
我將通過為 feedparser 項目創建構建腳本來介紹 Ant 構建腳本和 Python Ant 任務的基礎知識。為了使用 Python Ant 任務,您需要下載并安裝包含這些任務的 Java 庫。首先,從 參考資料 一節中列出的 URL 中下載 Python Ant 任務庫(pyAntTasks.jar)。然后,將 JAR 文件拷貝到 Eclipse 的 Ant 插件下的 lib 目錄中。這應該是 Eclipse 安裝目錄下形如 plugins/org.apache.ant_1.5.3 的子目錄。
Python Ant 任務庫拷貝完畢之后,必須在 Eclipse 中啟用庫。選擇 Window > Preferences,然后選擇 Ant > Runtime。將 Ant Home Entries 展開,其中可看到 Eclipse 使用的庫(JAR 文件)列表。選擇“ Add JAR”,然后從 Eclipse Ant 插件的 lib 目錄中選擇 Python Ant JAR 文件,就可以將剛剛拷貝的 Python Ant JAR 文件加入庫列表中(請參閱圖 8)。
圖 8. 向 classpath 中加入 Python Ant 任務
您現在應該能夠創建和運行包含 Python 任務的 Ant 構建腳本了。下面進入構建腳本內部!
創建構建腳本
我將逐步介紹如何創建一個簡單的 Python 構建腳本(請參閱清單 1)。完整的構建腳本 build.xml 可從 feedParserTest 項目的頂層目錄中找到。
清單 1. 用于編譯 Python 源代碼的構建腳本片斷
<project name="feedParserTest" default="compile">
<taskdef resource="pyAntTasks.properties"/>
<property name="src.dir" value="src"/>
<target name="compile">
<py-compile dir="${src.dir}" pythonpath="${src.dir}" optimize="0"/>
</target>
</project>
|
先介紹一個只編譯 Python 樣例代碼的構建腳本。<project> 標簽總是構建腳本的根標簽。<taskdef> 標簽聲明在整個構建腳本中使用的 Python 任務。在構建腳本的底部,可以定義 compile
目標。目標元素內部是 compile
運行期間執行的任務。特別的是 py-compile 任務,它負責從 src 目錄開始,編譯所有的 Python 代碼。該任務會遞歸遍歷所有的子目錄,并編譯所有的 Python 模塊。腳本中沒有采用將 src 目錄硬編碼到調用之處的方式,而是在構建腳本中定義了稱為 src.dir 的屬性。然后,在需要使用這個目錄名的時候,就可以通過 ${src.dir}
來引用。
要運行構建腳本,可從 Eclipse 中打開它。Eclipse 具有內置的 Ant 構建腳本編輯和瀏覽功能。Outline 視圖可以顯示出構建腳本的結構。在 Navigator 視圖中,選擇該構建腳本,用右鍵點擊,然后選擇“Run Ant...”。選擇 compile
目標,然后點擊“Run”。構建腳本執行過程中的輸出信息應該顯示在 Console 視圖中,表示運行成功。
Python 腳本執行任務
接下來將向構建腳本中加入新的目標,用于執行 Python 腳本(請參閱清單 2)。在本例中,可以將 RSS URL 作為參數來執行 feedparser.py 腳本。
清單 2. 運行 feedparser 腳本的構建腳本片斷
<target name="run.feedparser" depends="compile">
<py-run script="src/feedparser/feedparser.py" pythonpath="${src.dir}" optimize="0">
<arg value="http://www.ibm.com/developerworks/news/dw_dwtp.rss">
</py-run>
</target>
|
上面的目標以 RSS URL 為唯一的參數來執行 feedparser.py 腳本。該目標聲明為依賴于 compile
目標,所以后者將首先執行。實際上這一步并不是很必要,因為 Python 會根據需要自動編譯源代碼。如果您執行 run.feedparser
目標,就會運行 feedparser.py 腳本,同時將 RSS 的內容輸出到 Console 中。
Python 文檔任務
Python 的 API 文檔編制機制與 Java 技術中的 JavaDoc 系統類似,稱為 PyDoc。在構建腳本中加入清單 3 中列出的如下 XML 片斷,可為所有的 Python 模塊生成 PyDoc。
清單 3. 用于生成 PyDoc 的構建腳本片斷
1: <property name="pydoc.dir" value="pydoc"/>
2:
3: <target name="init">
4: <mkdir dir="${pydoc.dir}"/>
5: </target>
6:
7: <target name="pydoc" depends="init,compile">
8: <py-doc pythonpath="${src.dir}" destdir="${pydoc.dir}">
9: <fileset dir="${src.dir}">
10: <include name="**/*"/>
11: </fileset>
12: </py-doc>
13: </target>
|
從對上述 pydoc 目標的解析可看出,第 7 行聲明了目標名稱,并指出它依賴于 init
和 compile
目標。這意味著在運行 pydoc 目標之前,Ant 必須保證 init
和 compile
目標已經運行,如果沒有,則首先運行這兩個目標。
pydoc
目標所依賴的 init
目標在第 3 至第 5 行定義。 init
目標僅僅創建了一個存放 PyDoc API 文檔文件的目錄。如前所述,要為所生成文檔的保存位置定義一個屬性,名為 pydoc.dir。
第 8 行開始是 py-doc 任務。如前所述,您傳入生成 pydoc 過程中所使用的 PYTHONPATH
。 destdir
屬性告訴 py-doc 任務將生成的 HTML 文檔輸出到何處。
第 9 至第 11 行定義了在生成文檔的過程中應該處理哪些 Python 源文件。文件集是 Ant 腳本中通用的結構,可用于定義所操作的一組文件。這是一種很強大的特性,它使您能夠通過名字模式、布爾邏輯和文件屬性來選擇所要操作的文件。Ant 文檔中有這方面的完整描述。本例中遞歸選擇了“src”目錄下的所有文件。
Python 單元測試任務
Python 中具有標準的單元測試框架(從 Python 2.3 開始。在 Python 2.2 中這只是可選模塊),與 Java jUnit 框架十分類似。測試用例的結構與 jUnit 采用相同的方式。每一個待測試的類和模塊通常都具有自己的測試類。測試類中包含測試裝置(fixture),它們在 setUp
函數中初始化。每一個測試都編寫為測試類中的一個獨立的測試函數。unittest 框架會在測試函數之間循環往復,先調用 setUp
、再測試函數、然后清除( tearDown
)測試函數。請參閱清單 4 中的樣例。
清單 4. Python 單元測試模塊
import unittest
from pprint import pprint
import feedparser
class FeedparserTest(unittest.TestCase):
"""
A test class for the feedparser module.
"""
def setUp(self):
"""
set up data used in the tests.
setUp is called before each test function execution.
"""
self.developerWorksUrl = "testData/developerworks.rss"
def testParse09Rss(self):
"""
Test a successful run of the parse function for a
0.91 RSS feed.
"""
print "FeedparserTest.testParse09RSS()"
result = feedparser.parse(self.developerWorksUrl)
pprint(result)
self.assertEqual(0, result['bozo'])
self.assert_(result is not None)
channel = result['channel']
self.assert_(channel is not None)
chanDesc = channel['description']
self.assertEqual(u'The latest content from IBM developerWorks',
chanDesc)
items = result['items']
self.assert_(items is not None)
self.assert_(len(items)> 3)
firstItem = items[0]
title = firstItem['title']
self.assertEqual(u'Build installation packages with
solution installation and deployment technologies',
title)
def tearDown(self):
"""
tear down any data used in tests
tearDown is called after each test function execution.
"""
pass
if __name__ == '__main__':
unittest.main()
|
上述清單是實現 feedparser 模塊基本測試功能的測試類。完整的測試類見 feedParserTest 項目下的 src/feedparserTest/FeedparserTest.py。 setUp
函數負責準備整個測試過程中需要使用的測試裝置,在本例中只有測試用的 RSS 文件的目錄,測試函數將對其進行解析。 testParse09Rss
是真正的測試函數。這個函數調用 feedparser.parse 函數,傳遞測試用的 RSS 文件,輸出解析結果,并通過 TestCase 類的 assert 函數執行基本的檢查統作。如果任何 assert 的求值結果不是真,或是在執行過程中拋出任何異常,unittest 就會報告一次測試失敗或錯誤。最后的兩行負責在這個測試類內部運行測試,方法是直接運行該模塊即可。
要獨立運行該測試類,可以按前面所說的相同方式運行 FeedparserTest.py 模塊。在 Eclipse Navigator 視圖中選擇 FeedparserTest.py,然后通過 Python > Run 運行。此時顯示啟動配置窗口。除 Base 目錄之外,其他都保持缺省值即可。Base 目錄必須是 feedParserTest 項目的目錄,這樣才能在當前目錄下找到 RSS 文件(testData/developerworks.rss)。修改 base 目錄的設置,然后點擊“Run”。輸出信息顯示在 Console 上。
您也許希望我們編寫的所有單元測試都能夠作為構建的一部分自動執行。將下面清單 5 所示的構建片斷加入構建腳本便可實現。
清單 5. 執行單元測試的構建腳本片斷
1: <target name="tests" depends="compile">
2: <py-test pythonpath="${src.dir}" dir=".">
3: <fileset dir="${src.dir}">
4: <include name="**/*Test.py"/>
5: </fileset>
6: </py-test>
7: </target>
|
第一行是目標聲明,這與其他的腳本相同。第 2 至第 6 行調用 py-test 任務。這部分代碼將在“src”目錄下查找所有以“Test.py”結尾的所有文件,并運行所有測試。 PYTHONPATH
設置為“src”,測試執行的當前工作目錄就是當前目錄(‘.’)。
運行目標的方法是先運行構建腳本,再選擇執行“tests”目標。該目標將運行所有以“Test.py”結尾的測試用例,本例中僅有 FeadparserTest.py。
結束語
Eclipse 和 PyDev 插件的結合,以及 Apache Ant 與 Python Ant 任務一起使用,可以為 Python 開發提供完全集成的開發環境和構建/部署工具。這些工具尚在開發過程中,因此要經常查看是否有更新,如果您覺得特別希望看到某種特性,可以卷起袖管自力更生。
參考資料
|
|
關于作者
|
|
|
Ron Smith 是 RPS Technologies, Inc 的創始人。這是一家軟件開發與軟件顧問公司,總部位于芝加哥地區。Ron Smith 為客戶提供基于 J2EE 的企業應用程序發方面的咨詢,同時也在 RPS Technologies 內部開發軟件產品。可以通過 ron.smith@rpstechnologies.net與 Ron 聯系。
|