首页 > 解决方案 > 为什么 Python 3 中的索引字节返回一个 int 而不是字节?

问题描述

试图理解为什么获取字节对象的索引会返回一个您无法解码的 int,但切片会返回一个您可以解码的字节对象。这似乎不直观。当您对字符串执行相同操作时,在字符串位置获取索引仍会返回一个字符串。

在处理 Cryptopals 挑战时,我试图遍历一个字节数组以对 XORed 字符串进行频率分析,以计算纯文本字母的出现次数。我以为我可以执行以下操作,但我得到 'int' object has not attribute 'decode' 错误。从阅读 Python 文档来看,这是有道理的,字节数组是一个可变的整数序列,但是在解释器中进行测试时,我期待不同的行为。

str_a = bytearray(b'\x1b77316?x\x15\x1b\x7f+x413=x9x(7-6<x7>x:9;76')

for x in str_a:
    _ = x.decode('ascii').upper() 
    if _ in counts:
        counts[_] += 1

如果我将一个变量设置为单个字节,我可以在其上调用 decode()。我想我可以遍历字节字符串中的所有字节并以相同的方式解码(因此上面的循环)。但是,由于 r[0] 是一个 int,这不起作用。但是,如果我取 r[0:1],它会吗?我意识到我可以只调用 chr(r[0]),但我认为如果 r.decode() 有效,r[0].decode() 也应该有效。

>>> r = b'A'
>>> type(r)
<class 'bytes'>
>>> r.decode('ascii')
'A'
>>> r[0:1]
b'A'
>>> r[0:1].decode('ascii')
'A'
>>> type(r[0])
<class 'int'>
>>> r[0]
65
>>> r[0].decode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'decode'

字符串示例

>>> x = 'AB'
>>> type(x)
<class 'str'>
>>> x[0]
'A'
>>> type(x[0])
<class 'str'>

标签: python-3.x

解决方案


bytes对象作为 s 迭代的原因int是因为它们在概念上是字节的静态数组——从 0 到 255 的整数(根据PEP 358)——而不是交替编码的字符串。替代文本编码是一个常见的用例,但读取和写入任意二进制数据同样重要。

特别是关于str.encodeand bytes.decode,调用 不一定有意义some_bytes[0].decode,因为在许多编码中,字符可能被编码为多个字节。例如,b'a'.decode('utf-32')失败是因为 UTF-32 每个字符使用四个字节。


围绕PEP 467的讨论,其中建议添加,除其他外bytes.iterbytes,可能会提供额外的洞察力,bytes以了解它的行为方式。


推荐阅读