Как мне сделать так, чтобы IPython организовывал возможности завершения табуляции по классам? - PullRequest
4 голосов
/ 21 января 2009

Когда у объекта есть сотни методов, заполнение табуляции сложно использовать. Чаще всего интересными являются те методы, которые определены или переопределены классом проверяемого объекта, а не его базовыми классами.

Как я могу заставить IPython сгруппировать его возможности завершения табуляции, чтобы на первом месте были методы и свойства, определенные в классе проверяемого объекта, а затем в базовых классах?

Похоже, что недокументированная функция inspect.classify_class_attrs(cls) вместе с inspect.getmro(cls) дают мне большую часть необходимой мне информации (изначально она была написана для реализации функции help(object) Python).

По умолчанию readline отображает завершения в алфавитном порядке, но функцию, используемую для отображения завершений, можно заменить на ctypes или модуль readline, включенный в Python 2.6 и выше. Я переопределил отображение завершений readline, и он отлично работает.

Теперь все, что мне нужно, это метод объединения информации для каждого класса (от inspect.* для выше) с информацией для каждого экземпляра, сортировки результатов по порядку разрешения метода, симпатичной печати и разбивки на страницы.

Для дополнительного кредита было бы неплохо сохранить выбранное автозаполнение и отображать наиболее популярные варианты в первый раз при следующей попытке автозаполнения на том же объекте.

Ответы [ 3 ]

5 голосов
/ 29 января 2009

Поскольку я еще не использую 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 голос
/ 28 января 2009

Похоже, я могу использовать readline.set_completion_display_matches_hook([function]) (новое в Python 2.6) для отображения результатов. Завершитель будет возвращать список возможностей, как обычно, но также будет хранить результаты inspect.classify_class_attrs(cls), где это применимо. completion_display_matches_hook должен был бы содержать ссылку на завершитель, чтобы получить самый последний список завершений плюс информацию о классификации, которую я ищу, потому что только получает список имен совпадений в своих аргументах. Затем ловушка отображает список завершений в приятной форме.

1 голос
/ 22 января 2009

Я не думаю, что это можно сделать легко. В Ipython нет механизма для его выполнения в любом случае.

Изначально я думал, что вы можете изменить исходный код Ipython, чтобы изменить порядок (например, изменив функцию dir2() в genutils.py). Однако похоже, что readline в алфавитном порядке сортирует прохождения, которые вы передаете ему, так что это не сработает (по крайней мере, без lot дополнительных усилий), хотя, возможно, вы могли бы полностью исключить методы из базового класса. 1006 *

...