【发布时间】:2016-01-10 02:52:28
【问题描述】:
目标
我正在使用 pywin32 和 win32com 来操作来自第三方应用程序的 COM 对象。
我的一个对象是一个列表,我想迭代列表推导中的值。
什么有效
使用一些 COM 对象,我能够成功地执行以下操作:
>>> [obj.Name for obj in myCom.someList if 'Test' in obj.Name]
而且,正如预期的那样,我得到了一个结果列表:
['Test1', 'Test2', 'Test3']
什么不...
但是,在其他类似的列表对象上,我尝试了同样的事情:
>>> [obj.Name for obj in myCom.anotherList]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\Python27\lib\site-packages\win32com\gen_py\<class_string>.py", line 6575, in __iter__
raise TypeError("This object does not support enumeration")
TypeError: This object does not support enumeration
我尝试过的
所以我在定义my_iter后尝试添加函数:
>>> myCom.anotherList.__iter__ = my_iter
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\Python27\lib\site-packages\win32com\client\__init__.py", line 473, in __setattr__
raise AttributeError("'%s' object has no attribute '%s'" % (repr(self), attr))
AttributeError: '<win32com.gen_py.Thingy instance at 0xDEADBEEF>' object has no attribute '__iter__'
我用__getitem__ 和next 尝试了同样的事情,但我得到了同样的错误。我做了一些阅读,我认为这不起作用,因为与 __slots__... 不确定。
检查生成的 Python 源代码
在检查了第一个堆栈跟踪中显示的 .py 之后,我查看了 class ISomeList.__iter__ 的定义 - 因为它在帖子的第一个示例中完美运行。
from win32com.client import DispatchBaseClass
LCID = 0x0
class ISomeList(DispatchBaseClass):
def __iter__(self):
"Return a Python iterator for this object"
try:
ob = self._oleobj_.InvokeTypes(-4,LCID,2,(13, 10),())
except pythoncom.error:
raise TypeError("This object does not support enumeration")
return win32com.client.util.Iterator(ob, '{<<<guid>>>}')
并将其与 class IAnotherList.__init__ 进行比较:
class IAnotherList(DispatchBaseClass):
def __iter__(self):
"Return a Python iterator for this object"
try:
ob = self._oleobj_.InvokeTypes(-4,LCID,3,(13, 10),())
except pythoncom.error:
raise TypeError("This object does not support enumeration")
return win32com.client.util.Iterator(ob, None)
所以,对我来说,分配给ob 似乎失败了,然后我们引发了一个错误。
我可以修改生成的源以添加__iter__ 方法,但这似乎是一个非常“适用于我的机器”的解决方案。我能做什么?
【问题讨论】:
标签: python python-2.7 com pywin32