Python 3
我有一个通过win32com.client.Dispatch的COM对象,其中有许多方法用于自动化应用程序。我希望每次调用COM对象的任何方法时,python都会根据返回的值(实际记录)执行某些操作。
我的自动化伪代码是这样的:
obj = win32com.client.DispatchEx("3rdParty.Application")
obj.methodA(Parameter)
obj.methodB()
obj.non_method_call
obj.methodN()
...
当对obj进行任何方法调用时,我希望这个伪代码的意图发生:
x = obj.any_method(*args)
if x:
logger.debug(any_method.__name__ + ' was called at ' + datetime.now().strftime("%H:%M") + ' with parameters ' + str(*args)
else:
logger.error(obj.cerrmsg)
obj.logout
请注意,any_method.__name__
部分会很好,但并不重要。
python可以做到这一点,特别是对于COM对象,并且没有为有限的方法集编写逻辑吗?
装饰器听起来是正确的,因为它们修改了函数/类,但我查看的帖子在这种情况下不起作用(比如浏览对象的方法dict),然后我听说它们只适用于我自己的代码中定义的方法。建议@Property,但在这种情况下我无法解决如何应用它
高级技巧欢迎(getattr,元类,functools,包装等),但请演示。
答案 0 :(得分:0)
我测试了我在评论中提到的方法,针对win32com.client并遇到了一个基本问题:
self.__getattribute__
的递归性质意味着尝试存储对象然后使用self.stored_obj
失败,因为它永远递归地调用__getattribute__
。
如果你原谅一个全局变量的可怕使用作为一种hackish方式,并且意味着你一次只能使用它一次,它基本上有效。
即。调试/跟踪COM对象发生的事情可能没问题,但它不是一个好的或强大的解决方案:
global _wrapped_object
class LogWrap:
def __init__(self, object):
global _wrapped_object
_wrapped_object = object
def __getattribute__(self, name):
global _wrapped_object
next_hop_attr = _wrapped_object.__getattr__(name)
if callable(next_hop_attr):
def logging_attr(*args, **kwargs):
retval = next_hop_attr(*args, **kwargs)
print("logging a call to {0} with args -{1}-".format(name, ','.join(args)))
print("Returned: {0}".format(retval))
return retval
return logging_attr
else:
return next_hop_attr
def __setattr__(self, name, value):
global _wrapped_object
_wrapped_object.__setattr__(name, value)
from win32com.client import Dispatch
ie = Dispatch('InternetExplorer.Application')
ie = LogWrap(ie)
ie.Visible = True
ie.Navigate2('google.com')
使用示例输出:
>>> logging a call to Navigate2 with args -google.com-
Returned: None
>>>