当一个对象有数百种方法时,标签完成很难使用。通常情况下,有趣的方法是被检查对象的类而不是其基类定义或覆盖的方法。
如何让IPython对其选项卡完成的可能性进行分组,以便首先在被检查对象的类中定义的方法和属性,然后是基类中的方法和属性?
看起来未记录的inspect.classify_class_attrs(cls)
函数和inspect.getmro(cls)
给出了我需要的大部分信息(这些信息最初用于实现python的help(object)
功能)。
默认情况下,readline按字母顺序显示完成,但用于显示完成的函数可以用ctypes或Python 2.6及更高版本中包含的readline模块替换。我已经覆盖了readline的完成显示,效果很好。
现在我只需要一种方法来合并每个类的信息(从上面的inspect.*
)到每个实例的信息,按方法解析顺序排序结果,漂亮的打印和分页。
对于额外的功劳,最好存储所选的自动完成功能,并在下次尝试对同一个对象进行自动填充时首先显示最常用的选项。
答案 0 :(得分:5)
由于我还没有使用Python 2.6或3.0且没有readline.set_completion_display_matches_hook()
,我可以使用ctypes设置completion_display_func
,如下所示:
from ctypes import *
rl = cdll.LoadLibrary('libreadline.so')
def completion_display_func(matches, num_matches, max_length):
print "Hello from Python"
for i in range(num_matches):
print matches[i]
COMPLETION_DISPLAY_FUNC = CFUNCTYPE(None, POINTER(c_char_p), c_int, c_int)
hook = COMPLETION_DISPLAY_FUNC(completion_display_func)
ptr = c_void_p.in_dll(rl, 'rl_completion_display_matches_hook')
ptr.value = cast(hook, c_void_p).value
现在,当我按'tab'完成时,我自己的功能会打印完成列表。因此,它回答了“如何更改readline显示完成的方式”的问题。
答案 1 :(得分:1)
我认为这不容易实现。在任何情况下,Ipython都没有机制来执行它。
最初我以为你可以修改Ipython的源来改变顺序(例如通过改变genutils.py中的dir2()
函数)。然而,它看起来像readline按字母顺序排序传递给它的完成,所以这不起作用(至少没有很多更多努力),尽管你可以完全排除基类上的方法。
答案 2 :(得分:1)
看起来我可以使用readline.set_completion_display_matches_hook([function])
(Python 2.6中的新增功能)来显示结果。完成者将像往常一样返回一系列可能性,但也会在适用的情况下存储inspect.classify_class_attrs(cls)
的结果。 completion_display_matches_hook
必须持有对完成者的引用,以检索最新的完成列表以及我正在寻找的分类信息,因为它只在其参数中接收匹配名称列表。然后钩子以愉快的方式显示完成列表。