【问题标题】:How to define a binary string in Python in a way that works with both py2 and py3?如何以适用于 py2 和 py3 的方式在 Python 中定义二进制字符串?
【发布时间】:2011-10-13 13:45:49
【问题描述】:

我正在编写一个应该在 Python 2 和 3 中都可以工作的模块,我需要定义一个二进制字符串。

通常这类似于data = b'abc',但此代码代码在 Python 2.5 上因语法无效而失败。

我怎样才能以适用于所有 Python 2.5+ 版本的方式编写上述代码

注意:这必须是binary(可以包含任何类型的字符,0xFF),这一点非常重要。

【问题讨论】:

  • 二进制字符串?你的意思是bytes 对象吗?
  • b"abc" 语法和bytes() 构造函数是added in Python 2.6
  • 是的,我指的是字节。
  • 当以各种谷歌搜索方式搜索 python 2 和 python 3 时,这六个库和我的书(对此具有基本相似的工作解决方案)将出现在第一页上搜索结果。然而,似乎没有人知道它们中的任何一个存在。我们怎样才能解决这个问题?传播这个词!

标签: python python-3.x python-2.5


【解决方案1】:

我会推荐以下内容:

from six import b

这当然需要six module。 如果你不想这样,这里有另一个版本:

import sys
if sys.version < '3':
    def b(x):
        return x
else:
    import codecs
    def b(x):
        return codecs.latin_1_encode(x)[0]

More info.

这些解决方案(基本相同)有效、干净、尽可能快,并且可以支持所有 256 字节值(这里没有其他解决方案可以)。

【讨论】:

    【解决方案2】:

    如果字符串只有 ASCII 字符,请调用 encode。这将在 Python 2 中为您提供 str(就像在 Python 3 中的 b'abc')和 bytes

    'abc'.encode('ascii')
    

    如果没有,与其将二进制数据放在源中,不如创建一个数据文件,用'rb' 打开它并从中读取。

    【讨论】:

    • 正如您所怀疑的,我确实有几个非常小的二进制块,因此不能选择使用文件来存储它们。是的,它们具有非 ascii 值。
    • 那么,字符串实际上是什么样子的?如果它们是人类可读的字符串,请使用正确的编码对其进行解码。如果没有,则使用base64
    • 创建一个文件并从中读取?一个简单问题的复杂解决方案。抱歉,-1。
    • (而且使用ascii无故限制,改用latin1)。
    • @LennartRegebro:这在 Python 2 中是行不通的;试试'\xff'.encode('latin1')
    【解决方案3】:

    您可以存储base64编码的数据库。

    第一步是转换成base64:

    >>> import base64
    >>> base64.b64encode(b"\x80\xFF")
    b'gP8='
    

    这需要一次性完成,使用b 与否取决于您使用的 Python 版本。

    在第二步中,您将这个字节串放入没有b 的程序中。 然后确保它在py2和py3中都能正常工作。

    import base64
    x = 'gP8='
    base64.b64decode(x.encode("latin1"))
    

    在 2.6 中为您提供 str '\x80\xff'(也应在 2.5 中使用)和在 3.x 中提供 b'\x80\xff'

    除了上面两个步骤,你可以对十六进制数据做同样的事情,你可以这样做

    import binascii
    x = '80FF'
    binascii.unhexlify(x) # `bytes()` in 3.x, `str()` in 2.x
    

    【讨论】:

    • 糟糕,代码将变得非常神秘。我们不能找到适用于十六进制的解决方案吗?
    • 你试过Python3中的代码吗? binascii.unhexlify(x)TypeError: 'str' does not support the buffer interface
    • 我不明白 base64 部分应该做什么。你可以删除它,它仍然可以工作。
    • @sorin: 奇怪...这里在Python 3.1 (r31:73572, Jul 5 2010, 13:15:03) 中运行良好。也许x.encode("latin1") 在这里也能更好地工作......
    • @Lennart Regebro 它应该是一种替代方法,因为首选十六进制。 b'\x80\xff' 在 base64 中编码为 'gP8=',在十六进制中编码为 '80FF'
    猜你喜欢
    • 1970-01-01
    • 2017-09-24
    • 1970-01-01
    • 2012-09-02
    • 2011-10-13
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多