Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:中断内置输入()以设置新提示(在用户输入之前)_Python_Input_Command Prompt_Stdin_Python Multithreading - Fatal编程技术网

Python:中断内置输入()以设置新提示(在用户输入之前)

Python:中断内置输入()以设置新提示(在用户输入之前),python,input,command-prompt,stdin,python-multithreading,Python,Input,Command Prompt,Stdin,Python Multithreading,我有一个函数,它有一个连续循环,使用python的内置inputprompt请求用户输入。我还有一个单独的线程在做一些工作,当该线程中满足某个条件时,输入提示应该改变 这样,在启动时提示输入:但是在线程工作的中间,满足一个条件,所以提示应该切换到前进,类型:。现在,如果用户在第一个提示下没有输入任何内容,但是线程到达了提示被切换的点,那么我们仍然停留在有输入的第一个阻塞输入调用上:as it's prompt # Start the thread that does some work and

我有一个函数,它有一个连续循环,使用python的内置inputprompt请求用户输入。我还有一个单独的线程在做一些工作,当该线程中满足某个条件时,输入提示应该改变

这样,在启动时提示输入:但是在线程工作的中间,满足一个条件,所以提示应该切换到前进,类型:。现在,如果用户在第一个提示下没有输入任何内容,但是线程到达了提示被切换的点,那么我们仍然停留在有输入的第一个阻塞输入调用上:as it's prompt

# Start the thread that does some work and eventually changes the prompt
myThread.start()

#Start looping to ask for user input, get the prompt from the thread
while True:
    userInput = input(myThread.get_prompt())
    <do something with input>
我知道在执行stdin.readline之前,我可以通过选择[stdin]、[]、[]、0.0来轮询stdin来完成这一点,然后如果1得到用户输入,或者如果提示更改,则只需再次打印提示

然而,我想找到一个使用Python内置输入函数的解决方案,这样我就可以用Python的readline模块设置制表符完成

我试着用一个基本上每隔几秒钟就中断一次输入的信号来玩。有了这一点,我需要让它看起来天衣无缝,在没有重新打印提示的情况下进行新的输入调用。比如:

myThread.start()

while True:
   userInput = None
   signal(SIGALRM, handler)
   signal.alarm(3)
   try:
      userInput = input("\r" + myThread.get_prompt())
   except TimeoutError:
      pass
   finally:
      signal.alarm(0)  
   <do something with input>

def handler(signum, frame):
    raise TimeoutError
这很混乱,但是当它超时时,调用新的输入时,当前行缓冲区被打印出来,但光标在它的前面。因此,如果我键入aaa,它会重新打印aaa,但光标不在缓冲区的末尾,而是在缓冲区的开头

有什么建议吗


更新:我当然可以尝试更多地使用信号选项。这似乎是我目前为止最好的选择。如果用户已经开始键入内容,我似乎无法让光标移动到输入缓冲区的末尾。我不想让用户知道通话超时和再次被呼叫。

好的,我知道了。这比用信号警报来超时要好得多

如果将来有人偶然发现这个特定的问题,我基本上是这样做的:

import threading
import time
import readline
import sys

class MyThread(threading.Thread):
    def __init__(self):
        super(MyThread, self).__init__()
        # Set the initial prompt
        self.prompt = "Input: "

    def run(self):
        time.sleep(6)
        # Now we want to change the prompt so that next time input loop asks for prompt it is correct
        self.set_prompt("Go ahead, type: ")

        # Now overwrite what was there in the prompt
        sys.stdout.write("\r" + self.get_prompt())
        sys.stdout.flush()

        # Get the current line buffer and reprint it, in case some input had started to be entered when the prompt was switched
        sys.stdout.write(readline.get_line_buffer())
        sys.stdout.flush()

    def get_prompt(self):
        return self.prompt

    def set_prompt(self, new_prompt):
        self.prompt = new_prompt


# Create and start thread
myThread = MyThread()
myThread.start()

# Input loop
while True:
    userInput = input(myThread.get_prompt())
    print("Got: " + userInput)
如果您使用的是tab complete(我在这里没有显示),您可能会注意到,如果您在第一次提示切换后尝试tab complete,而不接受第一次提示的任何输入,那么tab complete仍然认为我们正在读取第一次提示,并将重新打印该提示。在这种情况下,您需要执行以下操作:

readline.set_completion_display_matches_hook(display)
其中display是一个函数,它执行的操作类似于我们的线程重写正确提示所必须执行的操作:

def display(substitution, matches, longest_match_length):
    # Print the matches
    print('')
    buffer = ''
    for match in matches:
        buffer += match + "     "
    print(buffer)
    # Rewrite the NEW prompt
    sys.stdout.write(<prompt>)
    sys.stdout.flush()
    sys.stdout.write(readline.get_line_buffer())
    sys.stdout.flush()

您可能不想使用输入,而是想使用类似curses的东西与终端交互,而不是使用简单地将提示写入一个流并从另一个流读取的输入。curses是否与python的readline一起用于制表符的完成?我没有使用过诅咒,但是快速查看一下文档似乎并不能提供一个简单的方法来实现它。不,它们是分开的。