Получение базового идентификатора объекта 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