如何在python中编写自动完成代码?

2024-09-28 15:09:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在Linux终端中编写自动完成代码。代码的工作原理如下。

它有一个字符串列表(例如,“你好”,“你好”,“再见”,“很好”…)。

在终端中,用户将开始输入,当有匹配的可能性时,他将得到可能的字符串的提示,他可以从中进行选择(类似于vim editorgoogle incremental search)。

他开始输入“h”,然后得到提示

h“埃洛”

“我”

你好吗

更好的方法是,它不仅从一开始就完成单词,而且从字符串的任意部分完成单词。

谢谢你的建议。


Tags: 方法字符串代码用户终端列表searchlinux
3条回答

我想你需要用户按下一个键。

您可以使用以下方法(无需按enter键)实现它:

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

然后,如果这个键是tab键(例如,这是您需要实现的),那么向用户显示所有的可能性。如果这是其他的键,请打印在标准输出上。

哦,当然,只要用户点击enter,就需要在一段时间内循环getkey()。你还可以得到一个方法,比如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 aprint a,所做的。

(我知道这并不完全是您所要求的,但是)如果您对选项卡上出现的自动完成/建议(如许多shell中所使用的那样)感到满意,那么您可以使用readline模块快速启动并运行。

下面是一个基于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

这将导致以下行为(<TAB>表示按下的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

在最后一行(HOTAB输入)中,只有一个可能的匹配,整个“你好”语句将自动完成。

有关readline的详细信息,请查看链接的文章。


"And better yet would be if it would complete words not only from the beginning ... completion from arbitrary part of the string."

这可以通过简单地修改completer函数中的匹配条件来实现,即从:

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

运行脚本时,请尝试键入Ctrl+r,然后键入a。这将返回包含“a”的第一个匹配项。再次输入Ctrl+r进行下一个匹配。要选择条目,请按回车键。

也可以尝试使用向上/向下键滚动关键字。

要在Python shell中启用自动完成功能,请键入以下内容:

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

(感谢http://blog.e-shell.org/221

相关问题 更多 >