子进程“TypeError:需要一个类似字节的对象,而不是“str""; [英] subprocess "TypeError: a bytes-like object is required, not 'str'"

查看:46
本文介绍了子进程“TypeError:需要一个类似字节的对象,而不是“str"";的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 几年前之前提出的问题中的此代码,但是,我认为这是过时的.尝试运行代码时,我收到上述错误.我仍然是 Python 的新手,所以我无法从类似的问题中得到太多的澄清.有谁知道为什么会这样?

I'm using this code from a previously asked question a few years ago, however, I believe this is outdated. Trying to run the code, I receive the error above. I'm still a novice in Python, so I could not get much clarification from similar questions. Does anyone know why this is happening?

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 前缀):

subprocess returns bytes objects for stdout or stderr streams by default. That means you also need to use bytes objects in operations against these objects. "Duration" in x uses str object. Use a bytes literal (note the b prefix):

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

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

or decode your data first, if you know the encoding used (usually, the locale default, but you could set LC_ALL or more specific locale environment variables for the subprocess):

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

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

The alternative is to tell subprocess.Popen() to decode the data to Unicode strings by setting the encoding argument to a suitable codec:

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

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

If you set text=True (Python 3.7 and up, in previous versions this version is called universal_newlines) you also enable decoding, using your system default codec, the same one that is used for open() calls. In this mode, the pipes are line buffered by default.

这篇关于子进程“TypeError:需要一个类似字节的对象,而不是“str"";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆