防止将回车 return "\r" 转换为 "\n"

prevent conversion of carriage return "\r" to "\n"

我在 t.py 中有以下代码:-

import time

for i in range(1,100):
    print(f"{i}% \r",end='')
    time.sleep(0.05)

它像这样在单行中计算 1 到 99:-

所以当我执行下面的代码时,我期望相同

import subprocess as sb
import sys

lol = sb.Popen('python t.py',stdout=sb.PIPE,shell=True,text=True)

while True:

    l = lol.stdout.read(1)
    if not l and lol.poll() is not None:
        break
    if(l == '\n'): # for checking
        print(" it should've been \r") # this should not happen

    sys.stdout.write(l)
    sys.stdout.flush()

print("done")

但是此代码在所有单独的行中打印 1% 到 99%。像这样:-

1%  it should've been \r

2%  it should've been \r

3%  it should've been \r

4%  it should've been \r

..... i have skipped this part .....

99%  it should've been \r

done

所以我加了一点if语句

    if(l == '\n'):
        print(" it should've been \r")

上面的 if 语句表明 '\r' 可能会以某种方式转换为我不想要的 '\n'。

好吧,它在文档中:(https://docs.python.org/3.8/library/subprocess.html#frequently-used-arguments):

"If encoding or errors are specified, or text (also known as universal_newlines) is true, the file objects stdin, stdout and stderr will be opened in text mode using the encoding and errors specified in the call or the defaults for io.TextIOWrapper."

"For stdout and stderr, all line endings in the output will be converted to '\n'. For more information see the documentation of the io.TextIOWrapper class when the newline argument to its constructor is None."

删除 text=True 标志以避免此行为。当您这样做时,请注意您从 stdout 读取的内容现在是字节数组而不是字符串,您必须相应地处理它们。

下面t.py和主脚本的实现就达到了你想要的效果。

t.py:

import time
import sys

for i in range(1,100):
    print(f'{i} \r', end='')
    sys.stdout.flush()
    time.sleep(0.2)

主脚本:

import subprocess as sb
import sys

lol = sb.Popen('python3 t.py',stdout=sb.PIPE,shell=True)

while True:


    l = lol.stdout.read(1)

    if not l and lol.poll() is not None:
        break

    print(l.decode("utf-8"), end="")

print("done")