Подтвердить что ты не робот

Как закодировать автозаполнение в python?

Я хотел бы закодировать автозаполнение в терминале Linux. Код должен работать следующим образом.

В нем есть список строк (например, "привет", "привет", "как вы", "прощай", "отлично",...).

В терминале пользователь начнет вводить текст, и когда есть возможность совпадения, он получает подсказку о возможных строках, из которых он может выбрать (аналогично vim editor или инкрементный поиск google).

например. он начинает набирать "h", и он получает подсказку

ч "ELLO"

_ "i"

_ "ow are you"

И еще лучше было бы, если бы он завершил слова не только с самого начала, но и из произвольной части строки.

Спасибо за советы.

4b9b3361

Ответ 1

(Я знаю, что это не совсем то, о чем вы просите, но) Если вы довольны автозавершением/предложениями, появляющимися на TAB (как используется во многих оболочках), вы можете быстро запускается и запускается с помощью модуля readline.

Вот быстрый пример, основанный на Doug Hellmann PyMOTW writeup на readline.

import readline

class MyCompleter(object):  # Custom completer

    def __init__(self, options):
        self.options = sorted(options)

    def complete(self, text, state):
        if state == 0:  # on first trigger, build possible matches
            if text:  # cache matches (entries that start with entered text)
                self.matches = [s for s in self.options 
                                    if s and s.startswith(text)]
            else:  # no text entered, all matches possible
                self.matches = self.options[:]

        # return match indexed by state
        try: 
            return self.matches[state]
        except IndexError:
            return None

completer = MyCompleter(["hello", "hi", "how are you", "goodbye", "great"])
readline.set_completer(completer.complete)
readline.parse_and_bind('tab: complete')

input = raw_input("Input: ")
print "You entered", input

Это приводит к следующему поведению (<TAB>, представляющему нажатие клавиши табуляции):

Input: <TAB><TAB>
goodbye      great        hello        hi           how are you

Input: h<TAB><TAB>
hello        hi           how are you

Input: ho<TAB>ow are you

В последней строке (H O TAB) введено только одно возможное совпадение, и все предложение "как вы" автоматически завершено.

Просмотрите связанные статьи для получения дополнительной информации о readline.


"И еще лучше было бы, если бы он завершил слова не только с самого начала... завершение из произвольной части строки".

Это может быть достигнуто путем простого изменения критериев соответствия в дополнительной функции, т.е. из:

self.matches = [s for s in self.options 
                   if s and s.startswith(text)]

к чему-то вроде:

self.matches = [s for s in self.options 
                   if text in s]

Это даст вам следующее поведение:

Input: <TAB><TAB>
goodbye      great        hello        hi           how are you

Input: o<TAB><TAB>
goodbye      hello        how are you

Обновления: использование буфера истории (как указано в комментариях)

Простым способом создания псевдо-меню для прокрутки/поиска является загрузка ключевых слов в буфер истории. Затем вы сможете прокручивать записи с помощью клавиш со стрелками вверх/вниз, а также использовать Ctrl + R для выполнения обратного поиска.

Чтобы попробовать, внесите следующие изменения:

keywords = ["hello", "hi", "how are you", "goodbye", "great"]
completer = MyCompleter(keywords)
readline.set_completer(completer.complete)
readline.parse_and_bind('tab: complete')
for kw in keywords:
    readline.add_history(kw)

input = raw_input("Input: ")
print "You entered", input

При запуске script попробуйте ввести Ctrl + R, а затем a. Это вернет первое совпадение, содержащее "a". Введите Ctrl + R снова для следующего совпадения. Чтобы выбрать запись, нажмите ENTER.

Также попробуйте использовать клавиши UP/DOWN для прокрутки ключевых слов.

Ответ 2

Думаю, вам нужно будет нажать клавишу, нажатую пользователем.

Вы можете добиться этого (без нажатия клавиши ввода) с помощью следующего метода:

import termios, os, sys

def getkey():
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    new = termios.tcgetattr(fd)
    new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
    new[6][termios.VMIN] = 1
    new[6][termios.VTIME] = 0
    termios.tcsetattr(fd, termios.TCSANOW, new)
    c = None
    try:
        c = os.read(fd, 1)
    finally:
        termios.tcsetattr(fd, termios.TCSAFLUSH, old)
    return c

Затем, если этот ключ является ключом вкладки (например, что-то, что вам нужно реализовать), тогда отобразите все возможности для пользователя. Если это любой другой ключ, напечатайте его на стандартном диске.

О, конечно, вам нужно будет затянуть getkey(), пока пользователь нажимает Enter. Вы также можете получить такой метод, как raw_input, который получит знак слова по знаку или отобразит все возможности, когда вы нажмете вкладку.

По крайней мере, этот предмет, с которого вы можете начать. Если вы достигнете каких-либо других проблем, чем напишите о них.

ИЗМЕНИТЬ 1:

Метод get_word может выглядеть следующим образом:

def get_word():
    s = ""
    while True:
        a = getkey()
        if a == "\n":
            break
        elif a == "\t":
            print "all possibilities"
        else:
            s += a

    return s

word = get_word()
print word

Проблема, с которой я сейчас сталкиваюсь, - это способ отображения знака, который вы только что ввели без каких-либо пробелов и пробелов, что делают print a и print a,.

Ответ 3

Чтобы включить автозаполнение в оболочке Python, введите следующее:

import rlcompleter, readline
readline.parse_and_bind('tab:complete')

(благодаря http://blog.e-shell.org/221)

Ответ 4

Шаги:

  • Создайте файл .pythonrc в домашнем каталоге этой командой: vi .pythonrc

  • Введите этот текст:

    import rlcompleter, readline  
    readline.parse_and_bind('tab:complete') 
    
  • Закройте файл

  • Теперь запустите

    echo "export PYTHONSTARTUP=~/.pythonrc" >> ~/.bashrc

  • Перезагрузите терминал

Ответ 5

Для тех (как я), которые в конечном итоге ищут автозаполнение в интерпретаторе:

(мертвая ссылка была здесь)

Это включает в себя создание файла .pythonrc, изменение .bashrc и import sys, которые вы должны импортировать каждый раз при запуске интерпретатора Python.

Интересно, может ли последняя быть автоматизированной для еще большего выигрыша.