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
也许在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)