如何在IPython中完成win32com代码?

Tob*_*ler 4 python autocomplete ipython win32com

通过

import win32com.client
wordapp = win32com.client.gencache.EnsureDispatch('Word.Application')
Run Code Online (Sandbox Code Playgroud)

我可以在这里Application记录一个Word 对象.但是,自动完成功能并不知道该API,有没有办法添加它?ipython

fug*_*ede 8

快速解决方案

也许在IPython(使用6.2.1测试)和Jupyter中实现代码完成的最简单方法是运行以下代码段:

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
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述

短篇小说

本指南中概述了一些更多细节,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)
Run Code Online (Sandbox Code Playgroud)

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通过添加以下五行来完全避免手动修补IPython core.completer.Completion.attr_matches:

try:
    ole_props = set(obj._prop_map_get_).union(set(obj._prop_map_put_))
    words += list(ole_props)
except AttributeError:
    pass
Run Code Online (Sandbox Code Playgroud)

相反,IPython 基于其代码完成__dir__,所以人们也可以修补gencache,这是代码生成最终发生的地方,包括喜欢的东西

def __dir__(self):
    return list(set(self._prop_map_get_).union(set(self._prop_map_put_)))
Run Code Online (Sandbox Code Playgroud)

每个生成的DispatchBaseClass.


小智 5

fuglede的答案很好,只是想将其更新为最新版本的IPython(7.1+)。由于IPython.utils.generics已从 using 更改simplegeneric为 using functools,因此该@complete_object.when_type方法应更改为@complete_object.register。所以他最初的代码应该改为:

from IPython.utils.generics import complete_object
import win32com.client

@complete_object.register(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
Run Code Online (Sandbox Code Playgroud)