Python中的win32.Dispatch和win32.gencache有什么优缺点?

26

我最近一直在使用Python的win32com.client作为Windows应用程序的API,但是我还不太理解一些基本的东西。

我一直在使用它与一个叫做WEAP的程序配合使用,使用方法如下:

import win32com.client
win32com.client.Dispatch("WEAP.WEAPApplication")

现在,我想在Excel中使用它,并找到了替代之前代码的方法,其中一种方法如下(来自Python: Open Excel Workbook using Win32 COM Api)。

import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
抱歉,我只能使用英语进行通信。
win32.Dispatch 
"并且"
win32.gencache.EnsureDispatch

还有其他的替代方法吗?有人知道每种方法的优缺点吗?或者在何时应该使用一种而不是另一种?

我寻找了建议并发现了一些有用的答案,例如:

Python:使用Win32 COM Api打开Excel工作簿

win32com.client.Dispatch可以工作,但win32com.client.gencache.EnsureDispatch不行

http://pythonexcels.com/python-excel-mini-cookbook/

https://mail.python.org/pipermail/python-win32/2011-August/011738.html

然而,它们通常着重于回答具体问题,而不是描述Dispatch、gencache.EnsureDispatch和更多可能的替代方法之间的区别的更大局面,这正是我想要的。

任何建议都将不胜感激。

2个回答

47

关于它,你需要阅读的一件事是这个链接

我会尽量简短地回答你的问题(最后可能不是很短...),但我不是专家。

当你用Python创建一个COM对象时,Python如何知道这个对象有哪些方法和参数可用?这涉及到earlylate绑定的概念。

如果你尝试使用Dispatch创建从未使用过的COM对象,你就无法知道该对象中有什么可用内容。如果我在Jupyter QtConsole中输入:

import win32com.client as win32
xl_dis = win32.Dispatch("Excel.Application")
xl_dis
Out[3]: <COMObject Excel.Application>

然后我尝试使用xl_dis,以查看之后我能做什么,但我将没有任何选择。我处于“动态绑定”的情况下,即“Python 不知道对象能做什么”。

如果我使用EnsureDispatch做同样的事情:

import win32com.client as win32
xl_ens = win32.gencache.EnsureDispatch("Excel.Application")
xl_ens
Out[3]: <win32com.gen_py.Microsoft Excel 14.0 Object Library._Application instance at 0x35671240>

首先,您可以从输出中看到差异,然后如果我执行xl_ens.,将获得一些可用的方法和参数。我现在处于早期绑定状态,并且“Python知道对象能做什么”。

发生的情况是,EnsureDispatch强制首先运行makepy.py(查看您的文件夹Lib\site-packages\win32com\client),以创建一个文件夹Lib\site-packages\win32com\gen_py,其中包含与此COM对象相关的一些方法和参数的Python脚本。

现在,如果您在新控制台中再次尝试使用Dispatch,您将获得完全相同的结果。确实,在使用EnsureDispatch之后,之前在win32com\gen_py中创建的文件夹仍然存在,“Python仍然知道对象能做什么”。要自行尝试,请转到\win32com\gen_py文件夹并删除包含Excel信息的文件夹(对我而言,名称为00020813-0000-0000-C000-000000000046x0x1x7,不确定您是否相同)。

最后,两者之间的一个区别主要在于是否在第一次创建COM对象时强制使用早期绑定,但如果与您的COM对象相关联的文件夹已经存在于\win32com\gen_py中,则没有太大区别。

这个链接提供了两个句子:

要强制使用早期绑定访问COM对象,必须在代码中强制执行MakePy过程。一旦确保支持MakePy存在,就像往常一样使用win32com.client.Dispatch()。它始终返回MakePy支持的COM对象包装器。

为了强制执行MakePy过程,使用win32com.client.gencache模块。此模块包含管理MakePy生成源文件的目录 - 生成的缓存或gencache的代码。该模块中有许多有用的函数,鼓励您浏览源文件,以便在需要执行这些生成文件的高级管理时使用。

总之,另一种选择是使用dynamic,例如win32.dynamic.Dispatch("Excel.Application"),您将始终获得后期绑定的COM对象。


1
非常感谢您的回答和提供的链接。我还有很多要学习,但这已经是一个不错的起点了! - Juan Ossa

13

生成的缓存位置可能在USER_PROFILE\AppData\Local\Temp\gen_py\PYTHON_VERSION\中。如果想清除缓存,这将非常有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接