在Python 2和3中将字符串转换为字节

13

我的函数需要接受字符串或二进制数据(例如从文件中读取)。如果是字符串,我想将其转换为原始数据(bytesbytearray)。

在Python 3中,我可以使用 data = bytes(data, 'utf8')。但是,在Python 2中失败了,因为它只接受一个参数。反之亦然,data = bytes(data) 在Python 2中有效,但在Python 3中则会抱怨需要一个编码才能工作。

为了说明问题,让我们假设所有输入(如果是字符串)都是UTF-8编码。那么,有没有比以下代码更好的方法来实现我所需的功能:

try:
  data = bytes(data, 'utf8')
except:
  data = bytes(data)

注意,data.encode() 在Py3中有效,但在Py2中会失败,如果字符串包含非ASCII字节。


为什么需要两个版本都能工作?难道你没有分别为它们准备的版本吗? - WakeskaterX
1
这是库代码,如果我可以使其版本无关,那就更好了。 - Xophmeister
3个回答

11

这适用于两个版本,即Python 2和Python 3

data = bytes(str(data).encode("utf-8"))

10

您可以使用sys.version_info检查版本:

if sys.version_info < (3, 0):
    data = bytes(data)
else:
    data = bytes(data, 'utf8')

它比依赖异常更符合Python的风格。


这也会在较旧版本的Python中失败。 - Padraic Cunningham
@PadraicCunningham 这个程序最低可以在哪个Python版本上运行? - Alex
4
Python社区采用了EAFP(宁愿请求原谅,也不要事先征得许可)的哲学。因此,实际上使用try/except比这种方式更符合Python风格。 - cowlinator
1
@cowlinator 您是正确的,如果您能捕获特定的异常。捕获通用异常是不好的实践。 - Alex
1
请注意,如果data包含非ASCII字符,则此代码在Python 2中会失败。 - dano
显示剩余2条评论

6

如果您正在使用 six py2/3 兼容性库,您可能更喜欢以下方式:

import six
data = bytes(data) if six.PY2 else bytes(data, 'utf8')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接