Python 2 vs 3:从字节串中获取字节的结果一致

Python 2 vs 3: consistent results with getting a byte from byte string

是否有任何简单的方法可以在 Python 2 和 Python 3 中获得与 "give me N-th byte in byte string" 类似的操作一致的结果?将字节作为整数或字节作为字符对我来说都可以,只要它们是一致的。

即给出

s = b"123"

天真的方法产生:

s[1] # => Python 2: '2', <type 'str'>
s[1] # => Python 3: 50, <class 'int'>

ord(...) 中包装会在 Python 中产生错误 3:

ord(s[1]) # => Python 2: 50, <type 'int'> 
ord(s[1]) # => Python 3: TypeError: ord() expected string of length 1, but int found

我能想到一个相当复杂的兼容解决方案:

ord(s[1]) if (type(s[1]) == type("str")) else s[1] # 50 in both Python 2 and 3

...但可能有一种我没有注意到的更简单的方法?

这样的事情怎么样?

import sys

if sys.version_info.major == 3:
    def index(s, n):
        return s[n]
elif sys.version_info.major == 2:
    def index(s, n):
        return ord(s[n])
else:
    raise NotImplementedError

长度为 1 的切片也将是 2.x 或 3.x 中的字节序列:

s = b'123'
s[1:2] # 3.x: b'2'; 2.x: '2', which is the same thing but the repr() rules are different.

如果您使用(如果需要则进行转换)bytearray 类型,两个版本的行为将相同,始终匹配 bytes 的 Python 3 行为。这是因为 bytearray 实际上是 Python 2 上的不同类型(具有 Python 3 行为),其中 bytes 只是 str 的别名。

更典型的解决方案是使用 six 兼容库,它提供了 six.indexbytes,因此在任何一个版本的 Python 上,您可以这样做:

>>> six.indexbytes(s, 1)
50