简体   繁体   English

sys.stdout.write \\ r回车,如何覆盖所有字符?

[英]sys.stdout.write \r carriage, how to overwrite all characters?

I'm playing with itertools.cycle and I'm using a simple list as input. 我正在使用itertools.cycle,正在使用一个简单的列表作为输入。 Then I write a while loop and I want to basically overwrite my output with each color as I iterate through them. 然后,我编写一个while循环,当我遍历它们时,我想基本上用每种颜色覆盖我的输出。 The sys.stdout.write('\\r' + colors) line does not overwrite all characters, only the length of the string of the next color. sys.stdout.write('\\r' + colors)行不会覆盖所有字符,仅覆盖下一个颜色的字符串的长度。 Lastly, I have a .5 second delay between each iteration. 最后,每次迭代之间有0.5秒的延迟。

import itertools
import time
colors = ['green', 'yellow', 'red']
traffic_light = itertools.cycle(colors)
while True:
    sys.stdout.write('\r' + next(traffic_light))
    sys.stdout.flush()
    time.sleep(.5)

When I get to 'yellow' in my loop, I am left with 'w' or 'low' when the shorter 'green' and 'red' strings are printed. 当我在循环中到达“黄色”时,当打印较短的“绿色”和“红色”字符串时,我留下“ w”或“ low”。 My output looks like this (after the first loop when 'yellow' is printed). 我的输出看起来像这样(在打印“ yellow”时的第一个循环之后)。

redlow
greenw
yellow

Can I completely overwrite the output with the '\\r' carriage? 我可以用'\\r'完全覆盖输出吗?

The carriage return '\\r' will send the cursor to the beginning of the line, where it can overwrite the existing text. 回车符'\\r'会将光标发送到该行的开头,在此处可以覆盖现有文本。 You can combine this with the sequence CSI K, which erases from the current cursor to the end of the line. 您可以将其与序列CSI K结合使用,该序列将从当前光标擦除到行尾。

Just replace \\r with \\r\\x1b[K . 只需将\\r替换为\\r\\x1b[K See ANSI escape code . 请参阅ANSI转义代码

import itertools
import sys
import time
colors = ['green', 'yellow', 'red']
traffic_light = itertools.cycle(colors)
while True:
    sys.stdout.write('\r\x1b[K' + next(traffic_light))
    sys.stdout.flush()
    time.sleep(.5)

Try out these additional escape sequences: 试用以下其他转义序列:

# Add color
colors = ['\x1b[32mgreen', '\x1b[33myellow', '\x1b[31mred']

Note the limitations of this technique... if the terminal is short enough that your text wraps, the program will move forward one line every time you print. 请注意此技术的局限性...如果终端足够短,以至于您的文字不能换行,则每次打印时程序都会向前移动一行。 If you need something more robust, curses gives you more power but it doesn't work out of the box on Windows. 如果您需要更强大的功能, curses可为您提供更多功能,但在Windows上无法立即使用。

You can calculate the maximum width of the color strings and then use str.ljust to pad the output with enough spaces to fill to the maximum width: 您可以计算颜色字符串的最大宽度,然后使用str.ljust在输出中填充足够的空间以填充到最大宽度:

import itertools
import time
import sys
colors = ['green', 'yellow', 'red']
traffic_light = itertools.cycle(colors)
max_width = max(map(len, colors))
while True:
    sys.stdout.write('\r' + next(traffic_light).ljust(max_width))
    sys.stdout.flush()
    time.sleep(.5)

Create a format string that left justifies to the max width. 创建一个格式字符串,该字符串左对齐至最大宽度。

import itertools
import time

colors = ['green', 'yellow', 'red']
fmt = f'\r{{:<{max(map(len, colors))}}}' # fmt = '{:<7}'

for color in itertools.cycle(colors):
    print(fmt.format(color), end='') # if needed add: flush=True
    time.sleep(.5)

Prior to 3.6 use fmt = '\\r{{:<{}}}'.format(max(map(len, colors))) . 在3.6之前的版本中使用fmt = '\\r{{:<{}}}'.format(max(map(len, colors)))

Alternatively use the .ljust() string method: 或者,使用.ljust()字符串方法:

import itertools
import time

colors = ['green', 'yellow', 'red']
width = max(map(len, colors))

for color in itertools.cycle(colors):
    print('\r' + color.ljust(width), end='') # if needed add: flush=True
    time.sleep(.5)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM