使用universal_newlines = True(使用bufsize = 1)和使用Popen的默认参数有什么区别?

Sta*_*tec 3 python subprocess popen python-3.x

我试图读取从Python调用的子进程的输出.为此我使用Popen(因为我不认为如果使用subprocess.call就可以管道stdout).

截至目前,我有两种方法可以做到这一点,在测试中,它似乎提供了相同的结果.代码如下:

with Popen(['Robocopy', source, destination, '/E', '/TEE', '/R:3', '/W:5', '/log+:log.txt'], stdout=PIPE) as Robocopy:
    for line in Robocopy.stdout:
        line = line.decode('ascii')
        message_list = [item.strip(' \t\n').replace('\r', '') for item in line.split('\t') if item != '']
        print(message_list[0], message_list[0])
    Robocopy.wait()
    returncode = Robocopy.returncode
Run Code Online (Sandbox Code Playgroud)

with Popen(['Robocopy', source, destination, '/E', '/TEE', '/R:3', '/W:5', '/log+:log.txt'], stdout=PIPE, universal_newlines=True, bufsize=1) as Robocopy:
    for line in Robocopy.stdout:
        message_list = [item.strip() for item in line.split('\t') if item != '']
        print(message_list[0], message_list[2])
    Robocopy.wait()
    returncode = Robocopy.returncode
Run Code Online (Sandbox Code Playgroud)

第一种方法不包括universal_newlines = True,因为文档说明这只有在universal_newlines = True时才可用,即在文本模式下.

第二个版本包含universal_newlines,因此我指定了bufsize.

有人可以向我解释一下这个区别吗?我找不到这篇文章,但我确实读过有关溢出缓冲区的问题,导致某种问题,从而导致使用的重要性for line in stdout.

另外,在查看输出时,不指定universal_newlines会使stdout成为一个bytes对象 - 但我不确定如果我只使用ascii(根据新行和制表符)比较universal_newlines模式来解码bytes对象会产生什么差异.

最后,设置bufsize1使输出"行缓冲",但我不确定这意味着什么.我很感激有关这些不同元素如何结合在一起的解释.谢谢

jfs*_*jfs 9

使用universal_newlines = True(使用bufsize = 1)和使用Popen的默认参数有什么区别?

默认值为:( universal_newlines=False意味着输入/输出被接受为字节,而不是Unicode字符串加上通用换行模式处理(因此参数的名称.Python 3.7提供 text了可能更直观的别名)被禁用 - 你得到二进制数据原样(除非Windows上的POSIX层混乱)和bufsize=-1(意味着流完全缓冲 - 使用默认缓冲区大小).

universal_newlines=True使用locale.getpreferredencoding(False)字符编码来解码字节(可能与ascii您的代码中使用的编码不同).

如果universal_newlines=False然后for line in Robocopy.stdout:迭代过度b'\n'分离的行.如果进程使用非ascii编码,例如,UTF-16用于输出,那么即使os.linesep == '\n'在您的系统上也是如此; 你可能得到错误的结果.如果要使用文本行,请使用文本模式:显式传递universal_newlines=True或使用io.TextIOWrapper(process.stdout).

第二个版本包含universal_newlines,因此我指定了bufsize.

一般情况下,没有必要指定bufsize您是否使用universal_newlines(您可以但不是必需的).而且您不需要bufsize在您的情况下指定.bufsize=1启用行缓冲模式(如果要写入,输入缓冲区将在换行符上自动刷新process.stdin),否则它等同于默认值bufsize=-1.