Получение базового идентификатора объекта OLE для объектов автоматизации win32com

Большинство встроенных типов данных и библиотек Python имеют смысл возвращать один и тот же объект (a is b, не просто a==b) даже если вы попросите об этом по-разному. Очень простой пример:

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

Однако, похоже, что это не так для многих видов нескалярных объектов, возвращаемых win32com автоматизации. Следующий код подключается к автоматизации sas-jmp, а затем получает два дескриптора к одному и тому же объекту таблицы данных. На уровне 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, у которого есть только несколько методов, ни один из которых не кажется подходящим к вопросу об идентичности объекта. Тем не менее repr() из _oleobj_ кажется, указывает на базовый объект автоматизации 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... ").

Существует ли лучший, более чистый способ сравнения идентификаторов объектов OLE с помощью win32com ?

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
Другие вопросы по тегам