将附加参数传递给python回调对象(win32com.client.dispatchWithEvents)
我正在努力处理回调对象,我是一个新手请友好: 我正在使用win32com包与windows应用程序交互(该应用程序并不重要) 简而言之,我试图实现的是订阅一个更新的表 我已经成功实现了一个回调,它在更新表时接收返回的数据,但我现在需要的是对接收到的数据进行操作 如果我可以用附加参数实例化回调对象(参见下面的代码),这个问题将很容易解决,但是我不知道如何做到这一点将附加参数传递给python回调对象(win32com.client.dispatchWithEvents),python,callback,arguments,win32com,Python,Callback,Arguments,Win32com,我正在努力处理回调对象,我是一个新手请友好: 我正在使用win32com包与windows应用程序交互(该应用程序并不重要) 简而言之,我试图实现的是订阅一个更新的表 我已经成功实现了一个回调,它在更新表时接收返回的数据,但我现在需要的是对接收到的数据进行操作 如果我可以用附加参数实例化回调对象(参见下面的代码),这个问题将很容易解决,但是我不知道如何做到这一点 回调类: 实例化回调对象: 编辑 实例化回调对象: #安装两个com对象 self.com1=win32com.client.D
回调类:
实例化回调对象:
编辑 实例化回调对象:
#安装两个com对象
self.com1=win32com.client.DispatchWithEvents(“WindowsApplication”回调事件)
self.com2=win32com.client.DispatchWithEvents(“WindowsApplication”回调事件)
#创建多个订阅(注意,这些订阅是异步的)
#推送订阅的信息不是问题,可以在其他地方完成
self.com1.Subscribe()
self.com2.Subscribe()
现在,当订阅信息点击回调对象时,我不知道是哪个com对象设置了订阅(我可以根据返回的信息猜测,但在设置相同的订阅时,这会导致问题),因为您可能只有一个应用实例,因此只有一个
DispatchWithEvents
,您可以简单地使参数成为类的成员:
class callBackEvents(object):
""" Callback Object for win32com
"""
params = None
def OnNewData(...
...
# populate the params field
callBackEvents.params = yourParams
self.app = win32com.client.DispatchWithEvents("WindowsApplication", callBackEvents)
当然,您可以将参数设置为全局参数,但您应该将全局参数仅作为最后手段或常量使用。我也遇到了同样的问题,并最终增加了DispatchWithEvents。请看下面我的解决方案(我认为更优雅): 处理程序类必须有一个init函数,并准备好按顺序接受参数:
class Handler_Class():
def __init__(self, cls):
self.cls = cls
def OnItemAdd(self, mail):
#Check if the item is of the MailItem type
if mail.Class==43:
print("##########",inbox, "##########")
print(mail.Subject, " - ", mail.Parent.FolderPath)
label = cls.label_email(datetime.now(),mail)
print("=======>",label)
您可以将其初始化为:
clsGED = classifier.PersonClassifier()
items = win32com.client.DispatchEx("Outlook.Application").GetNamespace("MAPI").Folders[<emailaddress>].Folders["Inbox"].Items
utilities.DispatchWithEvents(items, Handler_Class, [cls])
clsGED=classifier.PersonClassifier()
items=win32com.client.DispatchEx(“Outlook.Application”).GetNamespace(“MAPI”).Folders[].Folders[“收件箱”].items
实用程序.DispatchWithEvents(项目,处理程序类,[cls])
正如您可能已经猜到的,这里的应用程序用于一个数据科学项目,其中传入的电子邮件会自动分类,但新的DispatchWithEvents方法非常通用,并接受动态数量的参数。谢谢您的回答@Scholli,对不起,我应该更具描述性(我的第一个问题):我正在创建两个(或更多)DispatchWithEvents的实例,我有一个类可以创建实例并处理windows应用程序的输入。我所面临的困难是如何用应用程序的哪个实例实例化回调对象的信息来实例化回调对象?--许多的Thanks@JosephHughes你不能。扩展您的问题,以显示您实际尝试执行的操作(两个DispatchWithEvents实例),我相信我们可以找到一个替代方案。我已被告知,多个订阅将导致我正在测试的应用程序出现异常行为。因此,我已将你的回答标记为已接受。我还将扩展我的问题,尝试提供更多关于我试图实现的目标的信息,以防将来有人在为同样的目标而挣扎。
class callBackEvents(object):
""" Callback Object for win32com
"""
params = None
def OnNewData(...
...
# populate the params field
callBackEvents.params = yourParams
self.app = win32com.client.DispatchWithEvents("WindowsApplication", callBackEvents)
from win32com.client import Dispatch
from win32com.client import gencache
from win32com.client import getevents
from win32com.client import EventsProxy
import pythoncom
def _event_setattr_(self, attr, val):
try:
# Does the COM object have an attribute of this name?
self.__class__.__bases__[0].__setattr__(self, attr, val)
except AttributeError:
# Otherwise just stash it away in the instance.
self.__dict__[attr] = val
def DispatchWithEvents(clsid, user_event_class, arguments):
# Create/Get the object.
disp = Dispatch(clsid)
if not disp.__class__.__dict__.get("CLSID"): # Eeek - no makepy support - try and build it.
try:
ti = disp._oleobj_.GetTypeInfo()
disp_clsid = ti.GetTypeAttr()[0]
tlb, index = ti.GetContainingTypeLib()
tla = tlb.GetLibAttr()
gencache.EnsureModule(tla[0], tla[1], tla[3], tla[4], bValidateFile=0)
# Get the class from the module.
disp_class = gencache.GetClassForProgID(str(disp_clsid))
except pythoncom.com_error:
raise TypeError("This COM object can not automate the makepy process - please run makepy manually for this object")
else:
disp_class = disp.__class__
# If the clsid was an object, get the clsid
clsid = disp_class.CLSID
# Create a new class that derives from 3 classes - the dispatch class, the event sink class and the user class.
# XXX - we are still "classic style" classes in py2x, so we need can't yet
# use 'type()' everywhere - revisit soon, as py2x will move to new-style too...
try:
from types import ClassType as new_type
except ImportError:
new_type = type # py3k
events_class = getevents(clsid)
if events_class is None:
raise ValueError("This COM object does not support events.")
result_class = new_type("COMEventClass", (disp_class, events_class, user_event_class), {"__setattr__" : _event_setattr_})
instance = result_class(disp._oleobj_) # This only calls the first base class __init__.
events_class.__init__(instance, instance)
args = [instance] + arguments
if hasattr(user_event_class, "__init__"):
user_event_class.__init__(*args)
return EventsProxy(instance)
class Handler_Class():
def __init__(self, cls):
self.cls = cls
def OnItemAdd(self, mail):
#Check if the item is of the MailItem type
if mail.Class==43:
print("##########",inbox, "##########")
print(mail.Subject, " - ", mail.Parent.FolderPath)
label = cls.label_email(datetime.now(),mail)
print("=======>",label)
clsGED = classifier.PersonClassifier()
items = win32com.client.DispatchEx("Outlook.Application").GetNamespace("MAPI").Folders[<emailaddress>].Folders["Inbox"].Items
utilities.DispatchWithEvents(items, Handler_Class, [cls])