2014-09-26 43 views
3

大多數內置Python數據類型和庫使返回同一對象a is b,不只是a==b)即使你以不同的方式問它的一個點。一個很簡單的例子:讓底層的OLE對象標識對象

list = [ "foo", "bar", {"name": [1,2,3]} ] 
a = list[-1]["name"] 
b = list[2].values()[0] 
print (a is b) # True! 

然而,這似乎並沒有對多種由win32com自動化返回非標對象的情況下。以下代碼連接到自動化,然後獲取相同數據表對象的兩個句柄。在Python層面,這兩個自動化對象不共享一個身份:

from win32com.client import gencache 
mod = gencache.GetModuleForProgID("JMP.Application") 
app = mod.Application() 
table = app.GetTableHandleFromName("Table1") 
same_table = app.GetTableHandleFromName("Table1") 
print table 
print same_table 
print table is same_table 
# <win32com.gen_py.DCD36DE0-78F8-11CF-9E68-0020AF24E9FEx0x1x0.IAutoDataTable instance at 0x54418504> 
# <win32com.gen_py.DCD36DE0-78F8-11CF-9E68-0020AF24E9FEx0x1x0.IAutoDataTable instance at 0x54432456> 
# False 

看來,所有win32com OLE自動化對象也有一個_oleobj_財產。 _oleobj_是一個PyIDispatch object,它只有幾個方法,其中沒有一個似乎與對象身份問題相關。然而,_oleobj_repr()似乎指向底層OLE自動化對象:

print table._oleobj_ 
print same_table._oleobj_ 
# <PyIDispatch at 0x0000000003459530 with obj at 0x00000000003E2928> 
# <PyIDispatch at 0x0000000003459620 with obj at 0x00000000003E2928> 

爲了證實這兩個對象指向同一個底層的OLE對象,我已經使出解析repr()字符串和比較十六進制地址(「obj at 0x...」)。

使用win32com有更好,更簡潔的方式來比較OLE對象標識嗎?

回答

1

*意味在臉上*

自原來有一個很簡單的方法來做到這一點:http://mail.python.org/pipermail/python-win32/2014-October/013288.html

雖然is操作不起作用,因爲的Python對象是不同的, ==對象通過win32com包裝物件完成此目的:

from win32com.client import gencache 
mod = gencache.GetModuleForProgID("JMP.Application") 
app = mod.Application() 
table = app.GetTableHandleFromName("Table1") 
same_table = app.GetTableHandleFromName("Table1") 
print table is same_table, table._oleobj_ is same_table._oleobj_ 
print table==same_table, table._oleobj_==same_table._oleobj_ 
# False, False 
# True, True