快速解决方案
也许在 IPython 中实现代码完成的最简单方法(使用 6.2.1 测试,请参阅 the answer below 了解适用于 7.1 的 sn-p)和 Jupyter 运行以下 sn-p:
from IPython.utils.generics import complete_object
import win32com.client
@complete_object.when_type(win32com.client.DispatchBaseClass)
def complete_dispatch_base_class(obj, prev_completions):
try:
ole_props = set(obj._prop_map_get_).union(set(obj._prop_map_put_))
return list(ole_props) + prev_completions
except AttributeError:
pass
长篇小说
this guide 中概述了更多细节,win32com 附带一个脚本,makepy.py 用于生成与给定 COM 对象的类型库对应的 Python 类型。
对于 Word 2016,我们将按以下步骤进行:
C:\Users\username\AppData\Local\Continuum\Anaconda3\pkgs\pywin32-221-py36h9c10281_0\Lib\site-packages\win32com\client>python makepy.py -i "Microsoft Word 16.0 Object Library"
Microsoft Word 16.0 Object Library
{00020905-0000-0000-C000-000000000046}, lcid=0, major=8, minor=7
>>> # Use these commands in Python code to auto generate .py support
>>> from win32com.client import gencache
>>> gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 7)
makepy.py 的位置当然取决于您的 Python 发行版。同一目录下的脚本combrowse.py,可用于查找可用类型库的名称。
有了它,win32com.client 将自动使用生成的类型,而不是原始的IPyDispatch,此时,自动完成功能可用于例如IPython 或 Jupyter,因为感兴趣的 COM 对象实际上发布了它的可用属性和方法(这不是必需的)。
现在,在您的情况下,通过调用 EnsureDispatch 而不是 Dispatch,该过程的 makepy 部分会自动执行,因此您确实应该能够在 IPython 中为已发布的方法获得代码完成:
但请注意,虽然这确实为方法提供了代码补全,但对于属性则不然。可以使用_prop_map_get_ 属性检查那些。例如,wordapp.Selection.Range.Font._prop_map_get_ 给出了字体的所有可用属性。
如果使用 IPython 的要求不高,另请注意 PythonWin shell(位于 \pkgs\pywin32\Lib\site-packages\pythonwin\Pythonwin.exe 附近)具有对属性和方法的内置代码完成支持。
这本身就表明在 IPython 中同样可以实现。
具体来说,自动补全的逻辑又依赖于_prop_map_get_,可以在scintilla.view.CScintillaView._AutoComplete 中找到。另一方面,IPython 6.2.1 中的代码完成由core.completer.IPCompleter 处理。 IPython.utils.generics.complete_object 提供了用于添加自定义代码完成器的 API,如上面的第一个解决方案所示。一个问题是,complete_object 基于simplegeneric,对于任何给定类型只能提供一个完成者。幸运的是,makepy 生成的所有类型都将继承自 win32com.client.DispatchBaseClass。
如果这成为一个问题,也可以完全绕过complete_object,只需将以下五行添加到core.completer.Completion.attr_matches,手动修补IPython:
try:
ole_props = set(obj._prop_map_get_).union(set(obj._prop_map_put_))
words += list(ole_props)
except AttributeError:
pass
相反,IPython bases its code-completion on __dir__,因此也可以修补 gencache,这是代码生成最终发生的地方,以包含一些喜欢的东西
def __dir__(self):
return list(set(self._prop_map_get_).union(set(self._prop_map_put_)))
到每个生成的DispatchBaseClass。