getting underlying OLE object identity for win32com automation objects

风流意气都作罢 提交于 2019-12-10 21:23:45

问题


Most built-in Python data types and libraries make a point of returning the same object (a is b, not just a==b) even if you ask for it in different ways. A very simple example:

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

However, this doesn't seem to be the case for many kinds of non-scalar objects returned by win32com automation. The following code connects to sas-jmp automation and then gets two handles to the same data table object. At the Python level, these two automation objects don't share an identity:

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

It appears that all win32com OLE automation objects also have an _oleobj_ property. _oleobj_ is a PyIDispatch object, which only has a few methods, none of which seem pertinent to the question of object identity. However, the repr() of _oleobj_ seems to point to the underlying OLE automation object:

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

In order to confirm that two objects refer to the same underlying OLE object, I've resorted to parsing the repr() strings and comparing the hexadecimal addresses ("obj at 0x...").

Is there a better, cleaner way to compare OLE object identity using win32com?


回答1:


*Smacks self in face*

It turns out there's quite an easy way to do this: http://mail.python.org/pipermail/python-win32/2014-October/013288.html

Although the is operator does not work since the Python objects are distinct, the == object accomplishes this purpose with win32com-wrapped objects:

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


来源:https://stackoverflow.com/questions/26068864/getting-underlying-ole-object-identity-for-win32com-automation-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!