支持python 2和3:str,bytes或alternative

时间:2016-03-11 14:36:56

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

我有一个Python2代码库,它广泛使用str来存储原始二进制数据。我想支持Python2和Python3。

Python2中的bytes(al str)类型和Python3中的bytes完全不同。他们使用不同的参数来构造,索引到不同的类型,并且具有不同的strrepr

使用单一类型存储原始数据,统一两个Python版本代码的最佳方法是什么?

4 个答案:

答案 0 :(得分:2)

python-future包的Python3字节类型为backport

>>> from builtins import bytes  # in py2, this picks up the backport
>>> b = bytes(b'ABCD')

这提供了两者 Python 2和Python 3中的Python 3接口。在Python 3中,它是内置的bytes类型。在Python 2中,它是str类型之上的兼容层。

答案 1 :(得分:0)

我不知道你想用字节处理什么部分,我总是使用bytearray,这就是我从文件中读取时的方法

with open(file, 'rb') as imageFile:
    f = imageFile.read()
    b = bytearray(f)

我把这项工作从我正在进行的项目中解脱出来,它在2和3都适用。也许你可以看一下吗?

答案 2 :(得分:0)

如果您的项目小而简单,请使用six

否则我建议有两个独立的代码库:一个用于Python 2,一个用于Python 3.最初它可能听起来像很多不必要的工作,但最终它实际上更容易维护。

如果您决定在单个代码库中支持两个蟒蛇,那么作为您的项目可能成为的示例,请查看Google的protobuf。代码周围经常有违反直觉的分支,为了允许破解而修改的抽象。随着您的项目不断发展,它不会变得更好:截止日期与代码的质量相悖。

使用两个独立的代码库,您只需应用几乎相同的补丁,如果您需要单个代码库,那么与您之前的工作相比,这些补丁并不是很多。一旦包的Python 2用户数量下降,将更容易完全迁移到Python 3。

答案 3 :(得分:0)

假设您只需要支持Python 2.6及更高版本,您可以简单地使用bytes作为字节。使用b文字来创建字节对象,例如b'\x0a\x0b\x00'。处理文件时,请确保该模式包含b(如open('file.bin', 'rb')) 请注意,迭代和元素访问是不同的。在这些情况下,您可以编写代码以使用块。而不是b[0] == 0(Python 3)或b[0] == b'\x00'(Python 2)写b[0:1] == b'\x00'。其他选项是使用bytearray(当字节可变时)或辅助函数。

Python 2中的字符串应该是unicode,独立于Python 3移植;否则,遇到非ASCII字符时代码可能会出错。 Python 3中的等价物是str 使用u文字来创建字符串(例如u'Düsseldorf')和/或确保使用from __future__ import unicode_literals启动每个文件。必要时通过# encoding: utf-8启动文件来声明文件编码 使用io.open从文件中读取字符串。对于网络代码,获取字节并在其上调用decode以获取字符串。

如果您需要支持Python 2.5或3.2,请查看six以转换文字。

添加大量断言以确保对字符串进行操作的函数不会获取字节,反之亦然。像往常一样,具有100%覆盖率的良好测试套件有很大帮助。