Jak kodować autocompletion w Pythonie?
Chciałbym kodować autocompletion w Terminalu Linuksa. Kod powinien działać w następujący sposób.
Posiada listę ciągów (np. "hello", "hi", "how are you", "goodbye", "great",...).
W terminalu użytkownik zacznie wpisywać i gdy będzie jakaś możliwość dopasowania, otrzyma podpowiedź dla możliwych ciągów, z których może wybrać (podobnie jak w vim editor lub Google incremental search).
Np. zaczyna wpisywać " h " i dostaje hint
H "ello"
_ "i"
_"ow are you"
I jeszcze lepiej byłoby, gdyby dopełniało słowa nie tylko od początku, ale od dowolnej części łańcucha.
Dziękuję za radę.
5 answers
(wiem, że nie jest to dokładnie to, o co prosisz, ale) jeśli jesteś zadowolony z automatycznego uzupełniania / sugestii pojawiających się na karcie (używanej w wielu powłokach), możesz szybko rozpocząć pracę za pomocą modułu readline.
Oto szybki przykład oparty na Doug Hellmann ' s PyMOTW writeup on 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
W tym celu należy wykonać następujące czynności:]}
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
W ostatniej linijce (HOTAB wprowadzony), jest tylko jedno możliwe dopasowanie i całe zdanie "jak się masz" jest automatycznie uzupełniane.
Sprawdź połączone artykuły, aby uzyskać więcej informacji na temat readline
.
"i jeszcze lepiej byłoby, gdyby dopełniały słowa nie tylko od początku ... dopełnienie z dowolnej części łańcucha."
Można to osiągnąć po prostu modyfikując kryteria dopasowania w funkcji completer, tj. from:
self.matches = [s for s in self.options
if s and s.startswith(text)]
Do czegoś takiego:
self.matches = [s for s in self.options
if text in s]
To daje następujące zachowanie:
Input: <TAB><TAB>
goodbye great hello hi how are you
Input: o<TAB><TAB>
goodbye hello how are you
Aktualizacje: korzystanie z bufora historii (jak wspomniano w komentarzach)
Prostym sposobem utworzenia pseudo-menu do przewijania/wyszukiwania jest załadowanie słów kluczowych do bufora historii. Następnie będziesz mógł przewijać wpisy za pomocą klawiszy strzałek w górę/w dół oraz za pomocą Ctrl+R , aby wykonać wyszukiwanie odwrotne.
Aby spróbować tego out, wprowadzić następujące zmiany:
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
Po uruchomieniu skryptu spróbuj wpisać Ctrl+r , po którym następuje a . To zwróci pierwszy mecz, który zawiera "a". Enter Ctrl+r ponownie na następny mecz. Aby wybrać wpis, naciśnij ENTER .
Spróbuj również użyć klawiszy GÓRA/DÓŁ, aby przewijać słowa kluczowe.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-01 20:40:01
Myślę, że będziesz musiał nacisnąć klawisz przez użytkownika.
Możesz to osiągnąć (bez wciśnięcia enter) za pomocą metody takiej jak Ta:
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
Następnie, jeśli ten klucz jest klawiszem tab (na przykład jest to coś, co musisz zaimplementować), wyświetl wszystkie możliwości dla użytkownika. Jeśli to jakiś inny klucz, wydrukuj go na stdout.
Oh, oczywiście musisz mieć zapętloną getkey () za jakiś czas, o ile użytkownik naciśnie enter. Możesz również uzyskać metodę taką jak raw_input, która otrzyma cały znak słowa Po znaku lub wyświetl wszystkie możliwości, po naciśnięciu karty.
Przynajmniej od tego możesz zacząć. Jeśli osiągniesz jakieś inne problemy, napisz o nich.EDIT 1:
Metoda get_word może wyglądać tak:
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
Problem, który obecnie występuje, to sposób wyświetlania znaku, który właśnie wszedłeś bez żadnych enteres i spacji, co robi zarówno print a
, jak i print a,
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-03 07:44:59
Aby włączyć autouzupełnianie w powłoce Pythona, wpisz:
import rlcompleter, readline
readline.parse_and_bind('tab:complete')
(dzięki http://blog.e-shell.org/221 )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-23 19:50:00
Kroki:
Utwórz plik .pythonrc w katalogu domowym za pomocą tego polecenia:
vi .pythonrc
-
Wpisz tę treść:
import rlcompleter, readline readline.parse_and_bind('tab:complete')
-
Zamknij plik
-
Teraz biegnij
echo "export PYTHONSTARTUP=~/.pythonrc" >> ~/.bashrc
-
Uruchom ponownie terminal
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-02 09:30:39
Dla tych (jak ja), którzy kończą tutaj szukając autouzupełniania w interpreterze:
Wiąże się to z utworzeniem pliku .pythonrc
, modyfikacją .bashrc
i import sys
, które należy zaimportować przy każdym uruchomieniu interpretera Pythona.
Zastanawiam się, czy ta ostatnia może być zautomatyzowana dla jeszcze większej wygranej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 12:27:13