使用python进行动态终端打印
- 2025-03-20 08:48:00
- admin 原创
- 41
问题描述:
某些应用程序(例如 hellanzb)有一种以动态刷新数据的形式打印到终端的方式,有点像 top()。
在 Python 中,实现此目的的最佳方法是什么?我已经阅读了有关日志记录和 curses 的内容,但不知道该使用什么。我正在重新实现 top。如果您有任何其他建议,我也会接受。
解决方案 1:
如果您只需要更新一行(例如,创建进度条),最简单的方法是使用`'
'(回车)和
sys.stdout`:
import sys
import time
for i in range(10):
sys.stdout.write("
{0}>".format("="*i))
sys.stdout.flush()
time.sleep(0.5)
如果您需要支持移动指针等的适当控制台 UI,请使用curses
标准库中的模块:
import time
import curses
def pbar(window):
for i in range(10):
window.addstr(10, 10, "[" + ("=" * i) + ">" + (" " * (10 - i )) + "]")
window.refresh()
time.sleep(0.5)
curses.wrapper(pbar)
强烈建议使用该curses.wrapper
函数来调用您的主函数,它将在发生错误时负责清理终端,因此之后它不会处于无法使用的状态。
如果创建更复杂的 UI,则可以为屏幕的不同部分、文本输入框和鼠标支持创建多个窗口。
解决方案 2:
正如大多数答案已经指出的那样,在 Linux 上你真的别无选择,只能使用ncurses
。但是如果你不在 Linux 上,或者想要一些更高级的东西来创建你的终端 UI,该怎么办?
我个人觉得 Python 中缺少现代的跨平台终端 API 令人沮丧,因此编写了asciimatics来解决这个问题。它不仅为您提供了一个简单的跨平台 API ,还为UI 小部件和动画提供了很多高级抽象,可以轻松用于创建类似顶部的 UI。
解决方案 3:
如果使用属性“end”,则可以通过 print() 命令将输出发送到终端而无需滚动。
默认为 end='\n',即新行。
要抑制滚动并覆盖整个前一行,可以使用 RETURN 转义符 '\r'。
如果只想重写最后四个字符,可以使用一些退格键。
print(value, "_of_", total, end='
')
注意
这适用于标准系统终端。某些工具(如 IDLE)中的终端仿真器有错误,并且 '\r' 无法正常工作,输出只是与中间的一些不可打印字符连接在一起。
print() 的附加信息
在上面的示例中,“of”两侧的空格是为了确保我的值和单词“of”之间有空格。但是,print() 的默认分隔符是“ ”(空格),因此最终在“_of_”的值和下划线之间会有空格。
>> print (value, "_of_", total, end='
')
8 _of_ 17
分隔符属性 sep 可用于设置打印项之间的字符。在我的示例中,我将把它更改为空字符串 (''),以使我的输出符合我的需求。
>> print (value, "_of_", total, sep='', end='
')
8_of_17
解决方案 4:
我使用 破解了这个脚本curses
。这实际上是我为了好玩而做的一个临时解决方案。它不支持滚动,但如果您想在终端上构建一个具有多行的实时更新监视器,我认为它是一个很好的起点。
https://gist.github.com/tpandit/b2bc4f434ee7f5fd890e095e79283aec
以下是主要内容:
if __name__ == "__main__":
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
curses.start_color()
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK)
curses.init_pair(4, curses.COLOR_CYAN, curses.COLOR_BLACK)
try:
while True:
resp = get_data()
report_progress(get_data())
time.sleep(60/REQUESTS_PER_MINUTE)
finally:
curses.echo()
curses.nocbreak()
curses.endwin()
解决方案 5:
import time
for i in range(10):
print('
{}>'.format('='*i), end='')
time.sleep(0.5)
解决方案 6:
当我在 Unix 上的 shell 脚本中执行此操作时,我倾向于仅使用 clear 程序。您可以使用 Python subprocess 模块来执行它。它至少可以快速为您提供所需的信息。
解决方案 7:
我认为在这种情况下包含其他库并不是一个好的做法。因此,解决方案:
`print("
Current: %s %s" % (str(<value>), <another_value>), end="")`
扫码咨询,免费领取项目管理大礼包!