我有一个Python2代码库,它广泛使用str
来存储原始二进制数据。我想支持Python2和Python3。
Python2中的bytes
(al str
)类型和Python3中的bytes
完全不同。他们使用不同的参数来构造,索引到不同的类型,并且具有不同的str
和repr
。
使用单一类型存储原始数据,统一两个Python版本代码的最佳方法是什么?
答案 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%覆盖率的良好测试套件有很大帮助。