当前位置: 首页 > 面试题库 >

子进程“ TypeError:需要一个类似字节的对象,而不是'str'”

白禄
2023-03-14
问题内容

几年前,我正在使用一个先前提出的问题的代码,但是,我认为这已经过时了。尝试运行代码,我收到上述错误。我仍然是Python的新手,因此无法从类似的问题中得到很多澄清。有人知道为什么会这样吗?

import subprocess

def getLength(filename):
  result = subprocess.Popen(["ffprobe", filename],
    stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
  return [x for x in result.stdout.readlines() if "Duration" in x]

print(getLength('bell.mp4'))

追溯

Traceback (most recent call last):
  File "B:\Program Files\ffmpeg\bin\test3.py", line 7, in <module>
    print(getLength('bell.mp4'))
  File "B:\Program Files\ffmpeg\bin\test3.py", line 6, in getLength
    return [x for x in result.stdout.readlines() if "Duration" in x]
  File "B:\Program Files\ffmpeg\bin\test3.py", line 6, in <listcomp>
    return [x for x in result.stdout.readlines() if "Duration" in x]
TypeError: a bytes-like object is required, not 'str'

问题答案:

subprocess``bytes默认情况下返回stdout或stderr流的对象。这意味着您还需要bytes在针对这些对象的操作中使用对象。"Duration" in x使用str对象。使用字节文字(注意b前缀):

return [x for x in result.stdout.readlines() if b"Duration" in x]

或先解码数据(如果您知道所使用的编码)(通常是区域设置默认值,但可以为子流程设置LC_ALL或更具体的区域设置环境变量):

return [x for x in result.stdout.read().decode(encoding).splitlines(True)
        if "Duration" in x]

另一种方法是subprocess.Popen()通过将encoding参数设置为合适的编解码器来告诉将数据解码为Unicode字符串:

result = subprocess.Popen(
    ["ffprobe", filename],
    stdout=subprocess.PIPE, stderr = subprocess.STDOUT,
    encoding='utf8'
)

如果进行设置text=True(Python
3.7及更高版本,在以前的版本中称为universal_newlines),则还可以使用系统默认编解码器(用于open()调用的代码)启用解码。在这种模式下,默认情况下管道是行缓冲的。



 类似资料: