在Python中,是否可以在控制台中使用input()请求用户输入,同时在提示之前打印出行中的文本? 看起来应该是这样的:
Text 1
Text 2
Text 3
Please enter something: abc
每当打印新文本时,应在前一个文本之后和input()提示符之前打印。此外,它不应该中断用户输入文本。
因此,在打印" Text 4"控制台应如下所示:
Text 1
Text 2
Text 3
Text 4
Please enter something: abc
在没有使用任何外部库的情况下,这可以在Python中完成吗?
我已经尝试过使用\ r,\ b和类似的代码以及线程。 我也知道我可能需要有一个线程打印文本,而另一个请求用户输入。
答案 0 :(得分:2)
在Linux上你可以这样做:
#!/usr/bin/python
CURSOR_UP_ONE = '\x1b[1A'
ERASE_LINE = '\x1b[2K'
print('Text 1\nText 2\nText 3')
inp = ''
while inp != 'END':
inp = raw_input('Please enter something:')
print(CURSOR_UP_ONE + ERASE_LINE + inp)
重点在于每次将光标向上移动一行并删除行Please enter something:
。然后,您可以在其位置写入输入,并在需要时再次写入有关输入的通知。
CURSOR_UP_ONE
和ERASE_LINE
是具有特殊含义的字符串。完整列表,如果您可以找到那些终端转义控制序列HERE。
在某种程度上,也可以在Windows上使用此序列。例如。这些问题涉及这个主题:
答案 1 :(得分:2)
这是使用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')
这是一个在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')
答案 2 :(得分:1)
你可以通过这样的方式模仿你想要的东西:
import os
def clear(): os.system('cls')
screen = ""
prompt = ""
def printToScreen(s):
global screen, prompt
clear()
screen += (s + '\n')
print(screen)
print(prompt)
def promptToScreen(p):
global screen, prompt
clear()
print(screen)
s = input(p)
prompt = p + s
return s
#test:
while True:
s = promptToScreen("Enter anything -- or press 'Enter' to quit: ")
if len(s) > 0:
printToScreen(s)
else:
break
以下两个屏幕截图显示了它的工作原理:
然后:
这是一个Windows解决方案。在其他操作系统中 - 使用他们的命令清除屏幕。您可以通过编写clear()
使其更具可移植性,以便根据操作系统发出不同的命令。以上几乎是概念证明。关键的想法是维护一个字符串,表示您希望终端查看的方式,然后编写自己的打印函数,修改字符串,清除终端,然后将该屏幕打印到命令提示符。除非你做了一些奇怪的事情,否则开销的数量可以忽略不计,清除/更新对用户来说是不可见的。