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
?
*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