1. 程式人生 > >[轉]python---用Python實現COM物件

[轉]python---用Python實現COM物件

原文地址http://blog.sina.com.cn/s/blog_53b4587401017749.html
2009-07-21 18:02
from: http://hi.baidu.com/sinomazing/blog/item/611b85160d24f710972b43e1.html
作者:馬維峰 李林 王曉蕊
可以通過在元件式GIS開發中整合Python來提高開發效率和質量。Python可以在GIS系統開發中編寫資料的匯入匯出、處理、分析等模組,以及應用 系統的業務邏輯層和科學研究中的空間分析、地學建模等模組。Python和元件式GIS可以通過PythonCOM實現的Python的COM介面來集 成,在VB等開發語言中呼叫使用Python開發的COM伺服器元件,從而實現了GIS系統和Python擴充套件的獨立開發,無縫整合……

  1.1 初識Python

隨著計算機和地理資訊科技的飛速發展,GIS理論與應用的逐漸成熟,元件式技術已逐漸成為GIS 軟體的主流,改變了傳統整合式GIS 平臺的工作模式,更適合使用者進行二次開發以及與MIS、OA等其它系統的有機整合。代表性的元件式GIS有ERSI的ArcGIS和北京超圖的 SuperMap Object。SuperMap Object是由北京超圖公司和中科院地理與資源所開發研製的新一代大型元件式地理資訊系統平臺。
由於大多數的指令碼語言具有語法簡單,易於學習,解釋性、無需編譯,易於部署和維護 等優點,與直接使用靜態程式語言C、C++、VB等語言相比,使用動態指令碼語言開發效率更高,開發和維護難度較低,作為系統擴充套件和快速開發語言具有一般靜 態程式語言不具有的優勢。通過指令碼語言擴充套件或整合已有系統,在很多軟體平臺中得到了廣泛應用。在ArcGIS、SuperMap Object等基於COM的元件式地理資訊系統平臺中,可以通過Python等支援COM的指令碼語言對系統進行功能擴充套件,整合其他程式,編寫資料的匯入導 出、處理、分析等模組,特別是在應用系統開發的業務邏輯層(中間層)和科學研究中的空間分析、地學建模等方面更具優勢。

Python是一門解釋性、面向物件、動態語義特徵的高層語言(Lutz,2001)。Python具有高層的內建資料結構,動態型別和動態繫結,豐 富的標準和第三方擴充套件庫(包括科學計算、統計分析、視覺化等模組),簡單而易於閱讀的語法,使其非常適合作快速應用開發來開發新系統、擴充套件已有系統,或作 為膠水語言來連線、整合已有部件。有關Python的資訊和語法等請參考Python官方網站(http://www.python.org)。

本文將介紹如何應用Python來擴充套件SuperMap Object等元件式GIS的思路、方法和優勢。

1.2 應用Python來擴充套件元件式GIS

 1.2.1 Python的整合方式

在一般的程式語言中,整合或呼叫Python有以下幾種方式:(1)在C或C++語言中,可以利用Python提供的介面,呼叫Python的特定功 能(Rossum,2003);(2)通過資料檔案方式,通過作業系統的管道方式,直接呼叫Python執行環境和功能模組完成特定功能;(3)在 Windows環境下,可以使用PythonCOM擴充套件模組將Python編寫的物件包裝成COM物件,供支援COM的程式語言呼叫 (Hammond,2000)。其中(1)和(3)種方法為“無縫”整合,方法(2)為鬆散整合。

本文將通過PythonCOM擴充套件模組來完成與SuperMap Object相互呼叫。PythonCOM是由ActiveState公司開發的一個Python與COM、ASP整合的擴充套件模組,有關PythonCOM的資訊請參考ActiveState公司網站(http://www.activestate.com)。以下將詳細介紹如何建立一個可以被其他程式語言呼叫的Python模組,以及此模組如何與SuperMap Object互動完成特定的任務。

1.2.2 應用Python實現COM物件

使用Python實現一個COM物件首先需要定義一個Python類,實現需要的屬性和方法;其次需要應用PythonCOM擴充套件,實現 ProgID、CLSID等屬性,在登錄檔裡註冊這個Python類,使其成為一個可以被呼叫的COM物件。下面將通過一個簡單的例子來說明這個過程。
我們來設計一個可以計算使用者表示式的COM物件,以下是程式碼:
 # SimpleEVAL.py – 表示式求解
class PythonEVAL:
public_methods = [ ‘MyEval’ ]
reg_progid = “PythonGISDemos.EVAL”

Guid of this COM Searver

reg_clsid = “{6288B5B7-870F-494E-A4F0-99868729804E}”

def Myeval_r(self, source, my_x):
x = my_x
return eval_r(source)

自注冊部分

if name==’main‘:
print “Registering COM server…”
import win32com.server.register
win32com.server.register.UseCommandLine(PythonEVAL)
  以上的檔案定義有3個特殊的屬性欄位,分別是:

public_methods

可以被呼叫的方法列表,本程式碼只有一個方法“MyEval”。

reg_progid

物件的名稱,用來呼叫這個物件時使用。

reg_clsid

COM物件的CLSID,可以使用“pythoncom.CreateGuid()”這個方法來生成,也可以使用別的工具。

MyEval為我們定義的方法,引數為一個含“x”的表示式(字串),和x的具體值,然後呼叫這個方法,返回計算後的值。後面的部分為自注冊模組, 如果是在Python的互動環境下直接呼叫此模組,則執行這段程式碼。將這個檔案儲存在“Python23\Lib\site-packages”這個目錄 下,首先執行一次,使其在登錄檔裡註冊這個COM元件。

這個物件可以應用在某些需要使用者給出具體的表示式進行分析計算的模組中。在編寫這個類的過程中,可以在Python的互動環境下邊編寫邊測試,有助於驗證演算法和邏輯的正確性,保證開發效率和質量。

Python開發的COM物件也可以通過命令列進行註冊和反註冊。註冊一個物件:“Python.exe YourServer.py”;反註冊一個物件:“Python.exe YourServer.py –unregister”。需要說明的是這個物件一定要有以上程式的註冊部分這一段程式碼。

PythonCOM還定義了除了“public_methods”以外其他一些特殊的屬性欄位,可以描述COM物件的其他特性。在程式碼中,還可以 通過“raise COMException(“the error info”)”這樣的語句來進行錯誤處理。對於使用Python建立COM物件的其他細節問題請參考PythonCOM相關文件。

1.2.3 呼叫Python實現的COM物件

呼叫Python編寫的COM物件和呼叫其他COM物件方法一樣,以下將通過VB程式碼來例項說明其呼叫方法。

在VB中新建一個工程,在預設窗體上放置3個文字框和一個按鈕,在Form_Load事件裡編寫對COM物件的初始化程式碼,在按鈕點選事件裡,編寫COM物件呼叫的程式碼,在Form_Unload事件裡,銷燬這個物件。全部程式碼如下:
 Public myServer As Object
Private Sub Command1_Click()
Text3.Text=myServer.Myeval_r(Text1.Text,Int(Text2.Text))
End Sub
Private Sub Form_Load()
Set myServer = CreateObject(“PythonGISDemos.EVAL”)
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set myServer = Nothing
End Sub

整個程式碼和呼叫其他COM物件沒有什麼差別。以下是程式執行的介面,對x=2,表示式為“3*x – x*x”進行求解,結果是2。

圖 1 VB中呼叫Python編寫的COM物件的執行結果

我們可以把這段程式碼插入使用SuperMap Object等元件式GIS,開發語言為VB或其他語言的開發專案中需要使用者給出具體的表示式進行分析計算的模組中。需要說明的是,對於引數傳遞,資料類 型,物件呼叫等使用COM開發需要注意的問題,在這裡一樣需要注意。另外有兩個問題需要注意,第一,對於VB開發環境,VB是大小寫不敏感的,而 Python是區分大小寫的;第二是Unicode的問題,COM傳遞的字串都是Unicode,在Python中處理使用之前要根據需要轉換為Python的字串。

 1.3 應用例項

下面將使用Python來實現一個最小二乘擬合的模組。以下是程式碼:
 # LeastSq.py – 最小二乘擬合
from scipy import *
from scipy.optimize import leastsq
 class PythonSq:
public_methods = [‘AddX’,’AddY’,’leastsq’,’GetP’]
reg_progid = “PythonGISDemos.LeastSq”

Guid of this COM Searver

reg_clsid = “{6278B5B7-870F-494E-A4F0-92368724804E}”

程式中需要擬合的X和Y的值

x=[]
y=[]

輸入X和Y的值,由於一般語言沒有對應的序列等資料結構,所以逐個輸入

def AddX(self, xx):
self.x.append(xx)
def AddY(self, yy):
self.y.append(yy)

求解剩餘變數

def residuals(self, p, y, x):
a, b, c = p
y = array(y) #將序列轉換為矩陣
x = array(x)
err = y - (a*x*x + b*x + c)
return err

求解引數

def leastsq(self):
m_p = [1.0,1.0,1.0]
self.p = leastsq(self.residuals,m_p,args=(self.y,self.x))

求返回值

def GetP(self, index):
return self.p[0][index]

自注冊部分(略)

程式程式碼的說明見註釋。程式使用了SciPy擴充套件模組optimize模組(對於非線性方程,進行迴歸分析建議使用本方法,SciPy另外專門有線性代數模組(構建於ATLAS LAPACK和BLAS),可以進行線性代數運算,對於線性迴歸,具有更好的速度和穩定性。) (http://www.scipy.org),程式碼量很短,核心程式碼僅10餘行,主要處理了輸入和輸出,定義了剩餘變數的求解方式,主要的最小二次擬合 的程式碼僅1行,直接呼叫了optimize模組的leastsq方法。如果要改變擬合方程式,只需在residuals方法內修改“err = y - (a*x*x + b*x + c)”括號內的部分即可。資料通過逐個輸入方式輸入,然後由Python讀進其List中(如果需要傳遞大資料量的資料,筆者建議使用外部檔案方式,由 VB等客戶程式建立一個數據檔案,然後將此檔案路徑傳遞給Python的COM元件,由Python讀入(Python具有非常簡單的檔案讀取和寫入方式),構建為內部的List、Array或Matrix。) 。

在VB或其他語言中新建一個工程,測試此COM物件,以下為VB6下一個簡單的測試程式碼:

 Dim objSq As Object
Set objSq = CreateObject(“PythonGISDemos.LeastSq”)
Dim i As Integer
‘初始化迴歸值
For i = 0 To 100
objSq.AddX (CSng(i))
objSq.AddY (CSng(i) ^ 2 + Rnd())
Next
‘呼叫迴歸方法
objSq.leastsq
MsgBox “A = ” & objSq.GetP(0)
MsgBox “B = ” & objSq.GetP(1)
MsgBox “C = ” & objSq.GetP(2)
Set objSq = Nothing

對於非線性方程,需要給出引數的初始值(leastsq方法內的m_p的值)。我們也可以使用前面舉例介紹過的“eval”函式,編寫一個可以對任意 表示式進行求解的最小二次擬合模組。對於程式碼的編寫,可以首先在Python的互動式開發環境和IDE(Python自帶的IDLE,PythonWin 等)下,邊編寫邊測試,確定語法和邏輯沒有錯誤後,即可完成模組,然後在其他環境下測試和使用,可以提高開發效率和質量。

1.4 結論

通過PythonCOM介面,在基於COM的元件式GIS(例如SuperMap Object,ArcGIS)以及可以呼叫COM元件進行擴充套件的GIS工具的開發和擴充套件中整合Python,應用Python來開發部分功能元件具有以下優勢:

1) 充分發揮Python動態語言解釋性、語法簡單、易於閱讀、面向物件、動態語義、具有高層的內建資料結構等優勢,可以提高開發效率和開發質量,縮短開發週期;

2) 基於COM的元件式開發保證了GIS系統的開發和Python擴充套件的開發的獨立性,對於Python物件開發的元件,可以在任意時刻隨意修改(包括編譯打包後),不會影響GIS元件對其的呼叫;

3) 通過COM介面的呼叫和整合實現了Python和GIS工具的無縫整合;

4) Python優秀的科學計算、統計分析、視覺化等擴充套件模組(SciPy,見http://www.scipy.org)可以方便的應用在GIS的資料處理、空間分析、地學模型分析等領域;

5) Python豐富的標準庫和第三方擴充套件庫可以在GIS與MIS、OA等應用性系統的整合開發中發揮積極的作用。 附:本文所列的程式碼都在Python和VB等環境下測試通過,測試軟體環 境(Windows XP,VB 6.0,Python 2.3 + SciPy 0.3)。文中程式碼都略去了錯誤處理和捕獲,在實際應用中,應該使用適當的錯誤處理機制。程式中有關Python、SciPy擴充套件模組、COM、VB等的 語法和使用方法,請參考其官方網站和相應文件。