sys.stdout.write \ r \ n运输,如何覆盖所有字符?

问题描述 投票:0回答:3

我正在玩itertools.cycle并且我使用一个简单的列表作为输入。然后我写了一个while循环,我想基本上用每种颜色覆盖我的输出,因为我遍历它们。 sys.stdout.write('\r' + colors)行不会覆盖所有字符,只会覆盖下一种颜色的字符串的长度。最后,我在每次迭代之间有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)

当我在循环中变为“黄色”时,当打印较短的“绿色”和“红色”字符串时,我会留下“w”或“low”。我的输出看起来像这样(在打印'yellow'时的第一个循环之后)。

redlow
greenw
yellow

我可以用'\r'支架完全覆盖输出吗?

python python-3.x
3个回答
3
投票

您可以计算颜色字符串的最大宽度,然后使用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)

3
投票

回车'\r'将光标发送到行的开头,它可以覆盖现有文本。您可以将其与序列CSI K组合,序列CSI K从当前光标到行尾删除。

\r替换\r\x1b[K。见ANSI escape code

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)

尝试这些额外的转义序列:

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

请注意这种技术的局限性......如果终端足够短以至于文本包装,程序将在每次打印时向前移动一行。如果您需要更强大的功能,curses可以为您提供更多功能,但它在Windows上无法正常使用。


0
投票

创建一个格式字符串,左对齐最大宽度。

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)

3.6之前使用fmt = '\r{{:<{}}}'.format(max(map(len, colors)))

或者使用.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)
© www.soinside.com 2019 - 2024. All rights reserved.