使用 universal_newlines=True(bufsize=1)和使用 Popen 的默认参数有什么区别
What is the difference between using universal_newlines=True (with bufsize=1) and using default arguments with Popen
我正在尝试读取从 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
和
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
第一种方法不包括 universal_newlines=True,因为文档指出这是 only usable if universal_newlines=True i.e., in a text mode。
第二个版本确实包含 universal_newlines,因此我指定了一个 bufsize。
谁能给我解释一下区别?我找不到这篇文章,但我确实读到了有关缓冲区溢出导致某种问题的问题,因此了解了使用 for line in stdout
.
的重要性
此外,在查看输出时,未指定 universal_newlines 会使 stdout 成为 bytes
对象 - 但我不确定如果我仅使用 [=15 解码字节对象会有什么不同=](就新行和制表符而言)与 universal_newlines 模式相比。
最后,将 bufsize
设置为 1
会使输出 "line-buffered" 但我不确定这意味着什么。如果能解释一下这些不同的元素是如何结合在一起的,我将不胜感激。谢谢
What is the difference between using universal_newlines=True (with bufsize=1) and using default arguments with Popen
默认值是:universal_newlines=False
(意思是input/output被接受为 bytes,不是 Unicode 字符串加上 universal newlines mode 处理(因此参数的名称。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)
。
The second version does include universal_newlines and therefore I specify a bufsize.
一般情况下,如果您使用universal_newlines
,则不必指定bufsize
(您可以但不是必需的)。而且你不需要在你的情况下指定 bufsize
。 bufsize=1
启用行缓冲模式(如果您要写入 process.stdin
,输入缓冲区会在换行时自动刷新)否则它等同于默认的 bufsize=-1
.
我正在尝试读取从 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
和
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
第一种方法不包括 universal_newlines=True,因为文档指出这是 only usable if universal_newlines=True i.e., in a text mode。
第二个版本确实包含 universal_newlines,因此我指定了一个 bufsize。
谁能给我解释一下区别?我找不到这篇文章,但我确实读到了有关缓冲区溢出导致某种问题的问题,因此了解了使用 for line in stdout
.
此外,在查看输出时,未指定 universal_newlines 会使 stdout 成为 bytes
对象 - 但我不确定如果我仅使用 [=15 解码字节对象会有什么不同=](就新行和制表符而言)与 universal_newlines 模式相比。
最后,将 bufsize
设置为 1
会使输出 "line-buffered" 但我不确定这意味着什么。如果能解释一下这些不同的元素是如何结合在一起的,我将不胜感激。谢谢
What is the difference between using universal_newlines=True (with bufsize=1) and using default arguments with Popen
默认值是:universal_newlines=False
(意思是input/output被接受为 bytes,不是 Unicode 字符串加上 universal newlines mode 处理(因此参数的名称。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)
。
The second version does include universal_newlines and therefore I specify a bufsize.
一般情况下,如果您使用universal_newlines
,则不必指定bufsize
(您可以但不是必需的)。而且你不需要在你的情况下指定 bufsize
。 bufsize=1
启用行缓冲模式(如果您要写入 process.stdin
,输入缓冲区会在换行时自动刷新)否则它等同于默认的 bufsize=-1
.