繁体   English   中英

子进程“类型错误:需要一个类似字节的对象,而不是‘str’”

[英]subprocess "TypeError: a bytes-like object is required, not 'str'"

我正在使用几年前先前提出的问题中的此代码,但是,我认为这已经过时了。 尝试运行代码时,我收到上述错误。 我仍然是 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默认为 stdout 或 stderr 流返回bytes对象。 这意味着您还需要在对这些对象的操作中使用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]

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

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

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

就像错误所说的那样,“持续时间”是一个字符串。 而 X 是一个类似字节的对象,因为results.stdout.readlines()将输出中的行读取为字节码而不是字符串。

因此,将“持续时间”存储在一个变量中,比如 str_var 并使用str_var.encode('utf-8')其编码为字节数组对象。

请参阅[此][1]。

[1]: 在 Python 3 中将字符串转换为字节的最佳方法?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM