从sys.stdin读取,以按下回车键结束用户输入

5

我正在使用Py 3.6编写一个涉及用户输入的脚本。

在这个脚本中,用户被要求在shell中输入文本段落 - 可能包含换行符。然后将输入的文本保存到Python变量中以进行进一步处理。

由于用户输入可能包含换行符,因此我认为不能使用input(),而是使用sys.stdin.read()(如此处所建议)。

问题

读取输入正常工作,但是为了结束用户输入,用户必须按回车键,然后使用组合键CTRL + d(请参见此处)。 (请参见下面的当前过程

问题

  • 我希望用户只需按回车键即可结束对sys.stdin.read的输入(请参见下面的期望过程

编辑:也欢迎对使用CTRL + d的当前过程进行简化。

  • 这可行吗?

  • 这里有一些技巧here,但我想也许有更好的方法

当前代码

    # display text on screen
    print("Review this text\n" + text)
    # user will copy and paste relevant items from text displayed into Terminal
    user_input =  sys.stdin.read() 
    print ("hit ctrl + d to continue")
    # process `user_input`

当前流程

在下面的代码中,用户需要:

1)粘贴文本 2)按下RETURN以结束输入 3)按下Ctrl+d以移动到下一个文件

期望流程

我希望将其简化为:

1)粘贴文本 2)按下RETURN以结束输入并移动到下一个文件

在MacOSX上运行Python 3.5.6,使用终端进行文本输入。非常感谢您的任何帮助!


在读取操作之前,您可能需要print("按下ctrl + d继续") - Mad Physicist
你对转换为GUI界面有何感想?使用文本框和提交按钮可能更适合你。 - Kevin
@jasonharper 是的,那是一个好问题,但我在想可能有一种方法。如果需要,我会指定任何其他1键输入也可以接受。多行文本也将由用户复制并粘贴,如果有任何区别的话。 - patrick
您可能正在寻找无缓冲读取输入的方法,问题在于终端可能会在将输入传递给Python进程之前对其进行缓冲。请参阅以下链接:https://dev59.com/03E95IYBdhLWcg3wN7Kv#2409034 - geckos
复制/粘贴没有任何区别,因为您无法(真的;好吧,您可以关闭缓冲并一次读取一个字节,并查看输入频率,我猜)通过stdin中的“读取”来区分输入序列的时间。唯一的其他选择是立即想到的,您是否可以在输入的任何其他地方有空行(只是换行符)?如果没有,那么终止输入将相当简单,否则不是那么简单(可能也不是非常可靠)。 - Ondrej K.
显示剩余4条评论
1个回答

2

根据您在评论中的回复,如果以空行终止是可以接受的(即您的输入文本除了用于终止输入的换行符外,不能包含自己的换行符),那么这就很简单了:

user_input = ''          # User input we'll be adding to
for line in sys.stdin:   # Iterator loops over readline() for file-like object
    if line == '\n':     # Got a line that was just a newline
        break            # Break out of the input loop
    user_input += line   # Keep adding input to variable

我提到的另一种选项,虽然我并不真的喜欢这种方法的基础假设。您可以阅读输入并记录每个输入的时间。您可以定义一个时间限制,超过这个时间限制后,您可以放心地认为它不是作为单个块的复制粘贴的一部分。然后,单独的换行符被视为用户输入的结束。例如:

import sys
import time

COPY_PASTE_LIMIT = 0.5  # For instance 500ms
                        # Presuming platform time precision
                        # greater then whole seconds.

user_input = ''
last = 0  # We'll also later terminate when input was nothing
          # but an initial empty line.
for line in sys.stdin:
    now = time.time()
    if line == '\n' and (now - last > COPY_PASTE_LIMIT or last == 0):
        break
    last = now
    user_input += line

print(user_input)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接