在 python 中的 input() 提示之前打印文本

arc*_*t30 5 python cmd

在Python中,是否可以在控制台中使用input()请求用户输入,同时在提示之前打印出行中的文本?它应该看起来像这样:

Text 1
Text 2
Text 3
Please enter something: abc
Run Code Online (Sandbox Code Playgroud)

每当打印新文本时,都应该在前一个文本之后和 input() 提示之前打印它。此外,它不应中断用户输入文本。

因此,打印“Text 4”后控制台应如下所示:

Text 1
Text 2
Text 3
Text 4
Please enter something: abc
Run Code Online (Sandbox Code Playgroud)

是否可以在不使用任何外部库的情况下在 Python 中完成此操作?

我已经尝试过使用 \r、\b 和类似的代码以及线程。我还知道,我可能需要一个线程打印文本,而另一个线程请求用户输入。

PM *_*ing 3

这是使用 ANSI/VT100 终端控制转义序列的另一种方法。

我们告诉终端仅滚动终端的上部区域(打印输出数据的地方),以便下部区域(打印输入提示的地方)保持固定。当我们退出程序(使用Ctrl C)时,我们需要恢复默认的滚动设置。

该程序首先清除屏幕,然后循环提示用户输入一个数字n,然后打印 中的数字range(n),每行一个,有一点时间延迟,以便更容易看到发生了什么。每个范围的输出均延续前一个范围。如果用户输入非整数,则会重新打印提示。模块readline被导入,以便在输入提示时可以进行编辑和历史记录;该模块可能不适用于所有平台。

首先是 Python 2 版本。

''' Print text in a scrolling region of the terminal above a fixed line for input

    Written by PM 2Ring 2016.05.29

    Python 2 version
'''

from __future__ import print_function
from time import sleep
import readline

# Some ANSI/VT100 Terminal Control Escape Sequences
CSI = '\x1b['
CLEAR = CSI + '2J'
CLEAR_LINE = CSI + '2K'
SAVE_CURSOR = CSI + 's'
UNSAVE_CURSOR = CSI + 'u'

def emit(*args):
    print(*args, sep='', end='')

def set_scroll(n):
    return CSI + '0;%dr' % n

# Height of scrolling region
height = 40

GOTO_INPUT = CSI + '%d;0H' % (height + 1)

emit(CLEAR, set_scroll(height))

try:
    while True:
        #Get input
        emit(SAVE_CURSOR, GOTO_INPUT, CLEAR_LINE)
        try:
            n = int(raw_input('Number: '))
        except ValueError:
            continue
        finally:
            emit(UNSAVE_CURSOR)

        #Display some output
        for i in range(n):
            print(i)
            sleep(0.1)

except KeyboardInterrupt:
    #Disable scrolling, but leave cursor below the input row
    emit(set_scroll(0), GOTO_INPUT, '\n')
Run Code Online (Sandbox Code Playgroud)

这是在 Python 2 和 Python 3 上运行的版本。在 Python 3 上运行时,此脚本调用shutil.get_terminal_size()设置滚动区域的高度。在Python 2中可以获取终端大小,但是代码相当混乱,所以我选择了固定高度

我应该提到的是,如果终端大小在运行时发生更改,该脚本的两个版本都不能很好地应对。正确处理这个问题留给读者作为练习。:)

''' Print text in a scrolling region of the terminal above a fixed line for input

    Written by PM 2Ring 2016.05.29

    Python 2 / 3 version
'''

from __future__ import print_function
import sys
import readline
from time import sleep

if sys.version_info > (3,):
    # Get the (current) number of lines in the terminal
    import shutil
    height = shutil.get_terminal_size().lines - 1

    stdout_write_bytes = sys.stdout.buffer.write
else:
    height = 40
    input = raw_input
    stdout_write_bytes = sys.stdout.write


# Some ANSI/VT100 Terminal Control Escape Sequences
CSI = b'\x1b['
CLEAR = CSI + b'2J'
CLEAR_LINE = CSI + b'2K'
SAVE_CURSOR = CSI + b's'
UNSAVE_CURSOR = CSI + b'u'

GOTO_INPUT = CSI + b'%d;0H' % (height + 1)

def emit(*args):
    stdout_write_bytes(b''.join(args))

def set_scroll(n):
    return CSI + b'0;%dr' % n

emit(CLEAR, set_scroll(height))

try:
    while True:
        #Get input
        emit(SAVE_CURSOR, GOTO_INPUT, CLEAR_LINE)
        try:
            n = int(input('Number: '))
        except ValueError:
            continue
        finally:
            emit(UNSAVE_CURSOR)

        #Display some output
        for i in range(n):
            print(i)
            sleep(0.1)

except KeyboardInterrupt:
    #Disable scrolling, but leave cursor below the input row
    emit(set_scroll(0), GOTO_INPUT, b'\n')
Run Code Online (Sandbox Code Playgroud)