简体   繁体   English

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

[英]How to code autocompletion in python?

I'd like to code autocompletion in Linux terminal.我想在 Linux 终端中编写自动完成代码。 The code should work as follows.代码应该如下工作。

It has a list of strings (eg "hello, "hi", "how are you", "goodbye", "great", ...).它有一个字符串列表(例如“你好,”嗨,“你好吗”,“再见”,“很棒”,...)。

In terminal the user will start typing and when there is some match possibility, he gets the hint for possible strings, from which he can choose (similarly as in vim editor or google incremental search ).在终端中,用户将开始输入,当有匹配的可能性时,他会得到可能字符串的提示,从中他可以选择(类似于vim 编辑器谷歌增量搜索)。

eg he starts typing "h" and he gets the hint例如,他开始输入“h”并得到提示

h"ello"你好”

_ "i" _ “一世”

_"ow are you" _“你好吗”

And better yet would be if it would complete words not only from the beginning but from arbitrary part of the string.如果它不仅从开头而且从字符串的任意部分完成单词,那就更好了。

Thank you for advise.谢谢你的建议。

(I'm aware this isn't exactly what you're asking for, but) If you're happy with the auto-completion/suggestions appearing on TAB (as used in many shells), then you can quickly get up and running using the readline module. (我知道这不完全是您所要求的,但是)如果您对出现在TAB上的自动完成/建议感到满意(在许多 shell 中使用),那么您可以快速启动并运行使用readline模块。

Here's a quick example based on Doug Hellmann's PyMOTW writeup on readline .这是一个基于Doug Hellmann 在 readline的 PyMOTW 文章的快速示例。

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

This results in the following behaviour ( <TAB> representing a the tab key being pressed):这会导致以下行为( <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

In the last line ( H O TAB entered), there is only one possible match and the whole sentence "how are you" is auto completed.在最后一行(输入H O TAB )中,只有一个可能的匹配项,并且整个句子“你好”是自动完成的。

Check out the linked articles for more information on readline .查看链接的文章,了解有关readline更多信息。


"And better yet would be if it would complete words not only from the beginning ... completion from arbitrary part of the string." “更好的是,如果它不仅从头开始完成单词……从字符串的任意部分完成。”

This can be achieved by simply modifying the match criteria in the completer function, ie.这可以通过简单地修改完成函数中的匹配标准来实现,即。 from:从:

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

to something like:类似于:

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

This will give you the following behaviour:这将为您提供以下行为:

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

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

Updates: using the history buffer (as mentioned in comments)更新:使用历史缓冲区(如评论中所述)

A simple way to create a pseudo-menu for scrolling/searching is to load the keywords into the history buffer.创建用于滚动/搜索的伪菜单的一种简单方法是将关键字加载到历史缓冲区中。 You will then be able to scroll through the entries using the up/down arrow keys as well as use Ctrl + R to perform a reverse-search.然后,您将能够使用向上/向下箭头键滚动条目以及使用Ctrl + R执行反向搜索。

To try this out, make the following changes:要尝试此操作,请进行以下更改:

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

When you run the script, try typing Ctrl + r followed by a .运行脚本时,尝试键入Ctrl + r后跟a That will return the first match that contains "a".这将返回包含“a”的第一个匹配项。 Enter Ctrl + r again for the next match.再次输入Ctrl + r进行下一场比赛。 To select an entry, press ENTER .要选择一个条目,请按ENTER

Also try using the UP/DOWN keys to scroll through the keywords.还可以尝试使用向上/向下键滚动关键字。

To enable autocomplete in a Python shell, type this:要在 Python shell 中启用自动完成功能,请键入:

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

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

I guess you will need to get a key pressed by the user.我猜你需要让用户按下一个键。

You can achieve it (without pressing enter) with a method like this:您可以使用以下方法实现它(无需按 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

Then, if this key is a tab key (for example, that's something you need to implement), then display all possibilities to user.然后,如果此键是 Tab 键(例如,这是您需要实现的),则向用户显示所有可能性。 If that's any other key, print it on stdout.如果这是任何其他键,请将其打印在标准输出上。

Oh, of course you will need to have getkey() looped in a while, as long as the user hits enter.哦,当然你需要让 getkey() 循环一段时间,只要用户按下回车键。 You can also get a method like raw_input, that will get the whole word sign by sign, or display all the possibilities, when you hit a tab.您还可以获得像 raw_input 这样的方法,当您点击一个选项卡时,它将逐个符号获取整个单词,或显示所有可能性。

At least that's the item, you can start with.至少这是项目,你可以开始。 If you achieve any other problems, than write about them.如果您遇到任何其他问题,请写下它们。

EDIT 1:编辑 1:

The get_word method can look like this: 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

The issue I'm occuring right now is the way to display a sign, you have just entered without any enteres and spaces, what both print a and print a, does.我现在遇到的问题是显示标志的方式,您刚刚输入时没有任何输入和空格, print aprint a,作用。

You may want to checkout fast-autocomplete: https://github.com/seperman/fast-autocomplete您可能想签出快速自动完成: https : //github.com/seperman/fast-autocomplete

It has a demo mode that you can type and get results as you type: https://zepworks.com/posts/you-autocomplete-me/#part-6-demo它有一个演示模式,您可以在输入时输入并获取结果: https : //zepworks.com/posts/you-autocomplete-me/#part-6-demo

It is very easy to use:这是非常容易使用:

>>> from fast_autocomplete import AutoComplete
>>> words = {'book': {}, 'burrito': {}, 'pizza': {}, 'pasta':{}}
>>> autocomplete = AutoComplete(words=words)
>>> autocomplete.search(word='b', max_cost=3, size=3)
[['book'], ['burrito']]
>>> autocomplete.search(word='bu', max_cost=3, size=3)
[['burrito']]
>>> autocomplete.search(word='barrito', max_cost=3, size=3)  # mis-spelling
[['burrito']]

Disclaimer: I wrote fast-autocomplete.免责声明:我写了快速自动完成。

Steps:脚步:

  1. Create a file .pythonrc in home directory by this command: vi .pythonrc通过以下命令在主目录中创建一个文件 .pythonrc: vi .pythonrc

  2. Enter this content:输入此内容:

     import rlcompleter, readline readline.parse_and_bind('tab:complete')
  3. Close the file关闭文件

  4. Now run现在运行

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

  5. Restart the terminal重启终端

For those (like me) that end up here searching for autocomplete in the interpreter:对于那些最终在解释器中搜索自动完成的人(像我一样):

https://web.archive.org/web/20140214003802/http://conjurecode.com/enable-auto-complete-in-python-interpreter/ https://web.archive.org/web/20140214003802/http://conjurecode.com/enable-auto-complete-in-python-interpreter/

This involves creating a file .pythonrc , modifying .bashrc and an import sys you have to import every time you launch the Python interpreter.这涉及创建文件.pythonrc 、修改.bashrc和每次启动 Python 解释器时都必须导入的import sys

I wonder if the latter can be automated for even more win.我想知道后者是否可以自动化以获得更多胜利。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM