为什么在Python中用if语句无法直接对二进制数据进行判断?

bytes 由 Python 3 引入(2.x 内的 bytes 类型只是 str 的别名),使命是承载「数据」,而 str 类型在 Python 3 里面则应承载「文本」,这一区分事实上给出了更高层次的抽象,一切「文本」都是 Unicode 编码,只关心文本而不关心文本编码方式的用户可以不去操心文本在字节层面上究竟是怎么编码的;而需要操心数据在字节级别之细节的用户才需要去摆弄 bytes / bytearray 类型。

这一设计的动机源于 Python 2 中 str 的类型设计经常会困扰对于 encoding 缺乏了解的使用者。你想知道的「为什么这样」可以在 PEP 358 -- The "bytes" Object 中找到答案。

> 我要进行判断, 也不能很直觉的按照 16进制的写法来判断

Python 3 里面,str 是 str 的序列,bytes 却是 0 ~ 256 之间的数字的序列,也就是说

type('abc') == type('abc'[0]) # True
type(b'\x61\x62\x63') == type(b'\x61\x62\x63'[0]) # False !

原因大概也不复杂:你既然明知序列中每个成员都只可能是 0 ~ 256 之间的数字,为什么就不把它表达为一个数字?你当然可以很直觉地按照十六进制的写法来判断——我要提醒你,b'\x80' 不是 128 的十六进制写法,你后退一点,瞇着眼看这个写法,不觉得很奇怪么?你写下的明明是个 bytes 类型的 literal,你为什么要称它为一个数字的十六进制 literal ?让我们重温 Python 类型基础:数字的十六进制写法是: 0x80

所以正确的写法是:if i == 0x80

> 但在Python内部中, 到底是以什么形式存在的?

bytes 是 immutable 版本的 bytearray,阅读 CPython 源代码中 Include/bytearrayobject.h 可以看到 PyByteArrayObject 内部是用一个 char * 指针来存储数据的。

问题补充后面关于重新发明轮子的思考是好的,实际要干什么的话建议你还是用 JSON 或者 Protobuf 吧。
原发布于 https://www.zhihu.com/question/22312597/answer/20964094