对Python中的字节感到困惑

sas*_*uke 1 python binary-data

我最近开始使用Python解析二进制数据的活动,但我对Python处理"字节"项的方式感到困惑.请参考以下口译员对话:

>>> f = open('somefile.gz', 'rb')
>>> f
<open file 'textfile.gz', mode 'rb' at 0xb77f4d88>
>>> bytes = f.read()
>>> bytes[0]
'\x1f'
>>> len(bytes[0])
1
>>> int(bytes[0])  <---- calling __str__ automatically on bytes[0] ?
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '\x1f'
Run Code Online (Sandbox Code Playgroud)

上面的会话显示bytes [0]的大小为1个字节,但__str__表示是十六进制的.不用担心,但是当我尝试将字节[0]视为单个字节时,我会得到时髦的行为.

如果我想基于某些规范解析/解释二进制流,其中规范包括十六进制,二进制和十进制的表示,我将如何去做.

例如,"前两个字节是\xbeef,下一个是十进制8后跟一个打包位字段,其中字节的8位中的每一位代表一些标志?我猜有几个模块可以使这个任务变得容易但是我我想从头开始做.

我看过struct模块的引用,但没有引入新模块就没有办法直接检查读取的字节数?有点像bytes[0] == 0xbeef

有人可以帮我解决一下人们通常使用Python解析符合规范的二进制数据吗?谢谢.

Wee*_*ble 5

你正在使用Python 2.x. 在Python 3.0之前,读取文件,甚至是二进制文件,都会返回一个字符串.你所谓的"字节"对象实际上是一个字符串.像"bytes [0]"一样索引到字符串中只返回一个1个字符的字符串.

struct模块可能最适合你想要的东西,但如果你真的想要,你可以在没有它的情况下做你想要的:

"有点像字节[0] == 0xbeef?"

这不起作用,因为0xbeef是一个双字节序列,但bytes [0]只是一个字节.你可以这样做:

bytes[0:2] == b'\xbe\xef'
Run Code Online (Sandbox Code Playgroud)

在Python 3.x中,事情比你期望的更有效.读取二进制文件将返回一个bytes对象,其行为类似于1字节无符号整数序列,而不是字符串.