为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 Python3 str(bytes) 转换为文字字符串 b'<str>'

为什么 Python3 str(bytes) 转换为文字字符串 b'<str>'

慕尼黑8549860 2023-04-11 15:18:50
我正在使用 python3。以下是解释问题的示例。# python3Python 3.6.8 (default, Sep 26 2019, 11:57:09) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linuxType "help", "copyright", "credits" or "license" for more information.>>> import sys>>> sys.getdefaultencoding()'utf-8'>>> help(str) |  str(object='') -> str |  str(bytes_or_buffer[, encoding[, errors]]) -> str |   |  Create a new string object from the given object. If encoding or |  errors is specified, then the object must expose a data buffer |  that will be decoded using the given encoding and error handler. |  Otherwise, returns the result of object.__str__() (if defined) |  or repr(object). |  encoding defaults to sys.getdefaultencoding(). |  errors defaults to 'strict'.>>> d = b'abcd'>>> type(d)<class 'bytes'>>>> print(d)b'abcd'>>> len(d)4>>> m = str(d)>>> type(m)<class 'str'>>>> print(m)b'abcd'>>> len(m)7>>> m.encode()b"b'abcd'">>> >>> m = str(d, encoding='utf-8')>>> type(m)<class 'str'>>>> print(m)abcd>>> len(m)4>>> 在帮助(str)中提到“编码默认为 sys.getdefaultencoding()”仍然 str(d)转换带有 b'' 的字符串。注意字符串的长度现在是 7。问题是,为什么需要明确指定默认编码才能从字节中生成正确的字符串如何回到字节 - 新类型是字符串。(对字符串进行编码将添加额外的 b)有没有办法让 pylint 捕捉/警告这个问题。
查看完整描述

4 回答

?
慕后森

TA贡献1802条经验 获得超5个赞

str()for与is forbytes相同,正是因为您最终不会滥用它。这是一个更复杂的示例,其中源字符串是表情符号。repr()bytes


>>> s = "😸"

>>> len(s)

1  # One codepoint.

>>> b = s.encode("utf-8")

>>> len(b)

4  # Four bytes.

>>> print(b)

b'\xf0\x9f\x98\xb8'  # Repr of the bytes, not to be interpreted.

>>> print(repr(b))

b'\xf0\x9f\x98\xb8'  # Same as above!

>>> s2 = b.decode("utf-8")  # Decode back to string from bytes.

>>> s == s2

True

>>>

也就是说,使用str.encode()从字符串中获取字节,bytes.decode()从字节中获取字符串。


查看完整回答
反对 回复 2023-04-11
?
萧十郎

TA贡献1815条经验 获得超13个赞

您不是将其用作转换函数(如在 C 和 C++ 中),而是将其用作值的str字符串表示形式(要打印,因此它可能与 不同)。repr()

问题是二进制数组没有好的可打印字符串,所以我假设没有特定的str()函数,所以它退回到repr(),它添加了一些额外的注释(对于开发人员),比如前缀b'

在不知道编码的情况下,Python 无法将二进制数据转换为字符串。(二进制编码aASCII0x61中,字符串被解码a表示a)。

所以你可能想要d.decode('utf-8')

注意:系统编码是另一回事。它用于终端输入和输出,但不用于二进制数组,或从磁盘读取的一般数据。


查看完整回答
反对 回复 2023-04-11
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

有没有办法让 pylint 捕捉/警告这个问题


我认为 pylint 不会捕捉到它,但如果您愿意在代码中添加类型注释,mypy 会捕捉到它。


如果使用 flag 执行实例, Python 将在实例str上调用时发出警告。bytes-b


$ python3 -b -c 'str(b"a")'

-c:1: BytesWarning: str() on a bytes instance

请注意,警告只发出一次,AFAICT。


如果使用 执行-bb,将引发异常。


python3 -bb -c 'str(b"a")'

Traceback (most recent call last):

  File "<string>", line 1, in <module>

BytesWarning: str() on a bytes instance


查看完整回答
反对 回复 2023-04-11
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

如果指定了编码 [..],则对象必须公开一个数据缓冲区,该缓冲区将使用给定的编码 [..] 进行解码。object.__str__()否则,返回(如果已定义)或的结果repr(object)

这几乎可以回答您的问题。如果您省略encoding参数,则repr(object)使用,这将导致"b'...'"作为结果字符串值。如果您确实提供了encoding参数,那么它将尝试使用该编码解码提供的对象。这是两个根本不同的操作:

  1. 生成对象的字符串表示形式,这是非常安全的,不会真的失败。

  2. 解码二进制对象,即尝试以某种方式解释其内容,这很可能会失败。

这两个操作由两种不同的函数调用方式表示str。当您只希望执行 #1 时,您不希望隐式触发变体 #2 并有潜在的错误条件来处理一些隐式设置的全局值。


查看完整回答
反对 回复 2023-04-11
  • 4 回答
  • 0 关注
  • 134 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信