在 Python 中确定对象是否为类字节对象的正确方法是什么?

新手上路,请多包涵

我的代码期望 str 但将按以下方式处理传递 bytes 的情况:

 if isinstance(data, bytes):
    data = data.decode()

不幸的是,这在 bytearray 的情况下不起作用。是否有更通用的方法来测试对象是 bytes 还是 bytearray ,还是我应该检查两者? hasattr('decode') 是否如我所想的那样糟糕?

原文由 A. Wilcox 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 392
2 个回答

您可以在此处使用几种方法。

鸭子打字

由于 Python 是 duck typed ,您可以简单地执行以下操作(这似乎是通常建议的方式):

 try:
    data = data.decode()
except (UnicodeDecodeError, AttributeError):
    pass

但是,您可以按照您的描述使用 hasattr ,这可能没问题。当然,这是假设给定对象的 .decode() 方法返回一个字符串,并且没有讨厌的副作用。

我个人推荐异常或 hasattr 方法,但无论你使用什么都取决于你。

使用 str()

这种方法不常见,但有可能:

 data = str(data, "utf-8")

其他编码是允许的,就像缓冲区协议的 .decode() 。您还可以传递第三个参数来指定错误处理。

单分派通用函数 (Python 3.4+)

Python 3.4 及更高版本通过 functools.singledispatch 包含一个称为单分派通用函数的漂亮功能。这有点冗长,但也更明确:

 def func(data):
    # This is the generic implementation
    data = data.decode()
    ...

@func.register(str)
def _(data):
    # data will already be a string
    ...

如果您愿意,也可以为 bytearraybytes 对象创建特殊处理程序。

当心:单分派函数仅适用于第一个参数!这是一个有意的功能,请参阅 PEP 433

原文由 Elizafox 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用:

 isinstance(data, (bytes, bytearray))

由于这里使用了不同的基类。

 >>> bytes.__base__
<type 'basestring'>
>>> bytearray.__base__
<type 'object'>

检查 bytes

 >>> by = bytes()
>>> isinstance(by, basestring)
True

然而,

 >>> buf = bytearray()
>>> isinstance(buf, basestring)
False

以上代码是在python 2.7下测试的

不幸的是,在 python 3.4 下,它们是相同的….

 >>> bytes.__base__
<class 'object'>
>>> bytearray.__base__
<class 'object'>

原文由 zangw 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题