我知道这看起来很简单,我想问题是我对所有这些字节str unicode(和编码解码,坦率地说)还没有一个清晰的理解。
我一直在尝试让我的工作代码在Python 3上运行。我遇到的问题是当我用lxml
解析一个XML并解码该XML中的base64字符串时。
代码现在按以下方式工作:
我使用XPath查询'.../binary/text()'
检索二进制数据。这将生成一个包含lxml.etree._ElementUnicodeResult
对象的单元素列表。然后,使用python 2,我能够:
decoded = source.decode('base64')
最后
output = numpy.frombuffer(decoded)
但是,在python 3上,我得到一条错误消息,说
AttributeError: 'lxml.etree._ElementUnicodeResult' object has no attribute 'decode'
这并不奇怪,因为lxml.etree._ElementUnicodeResult
是str
的一个子类。
另一种方法是使用
binary = tree.xpath('//binary')[0]
binary_string = binary.text
这基本上是一样的。那么我该怎么从base64解码呢?我已经看过base64
模块,但是它接受一个bytes
对象作为参数,我想不出将str
表示为bytes
的方法,因为如果我尝试构造一个bytes
对象,Python将尝试对字符串进行编码,这是我不需要的。
进一步搜索,我发现了binascii
模块(如果我没有弄错的话,它是从base64
间接调用的),但是对我的字符串调用binascii.b2a_base64()
会产生
TypeError: 'str' does not support the buffer interface
另外,我甚至在how to decode a hex string in Python 3上找到了一个答案,但是这是用一个专用的方法完成的,所以我看不出它有什么帮助。
有人能告诉我我缺了什么吗?恐怕大部分帖子都无关紧要,只会加重我的羞耻感,但至少你们知道what I tried。
我没有安装Python3,但听起来您需要将从lxml返回的Unicode转换为字节,也许可以通过调用.encode('ascii')?
好吧,我想我要总结一下我目前对事物的理解(请随意纠正我)。希望它能帮助其他人,就像我一样困惑。
当然,功劳完全归于thebjorn和delnan。
所以,从最常见的事情开始: 这里有Unicode,它是一个全球标准,为所有你能想象到的外来字符分配代码(或代码点)。这些代码只是整数。维基百科称,截至Unicode 6.1,共有109975个图形字符。
还有一些编码定义了如何用字节码指定Unicode字符。一个字节不足以指定任意Unicode字符。尽管如此,如果只取其中的一小部分(英文字母表、数字、标点符号、一些控制字符),每个字符只需一个字节(甚至7位;请参见ASCII)。
要在任何地方传递Unicode字符串,需要对其进行字节编码,然后在另一端进行解码。
在Python 2中,
str
实际上是字节,unicode
是Unicode,但是python2会在需要时为您执行隐式编码/解码。它将尝试使用ASCII编码。在Python 3中,
str
始终是Unicode字符串,bytes
是实际字节的新数据类型。Python 3从不进行隐式转换,您始终需要自己进行转换并指定编码。这意味着你的程序只有在你了解发生在我身上的事情后才能运行。现在,这或多或少是清楚的,让我们转到base64编码,这也是一种分类编码,但有一个稍微不同的含义。 假设您有一些二进制数据(即字节),它们可能意味着任何东西(在我的例子中是一堆
float
)。现在要用字符串表示这个二进制数组。这就是base64编码的含义:您的字节被表示为ASCII字符串。Base64表示6位,因此在Base64编码的字符串中,单个字符代表6位数据。这就是为什么base64编码字符串的长度必须是4的倍数:否则编码的字节数将不是整数。
最后,要从base64解码,需要一个ASCII字符串。Unicode字符串不行,只能有base64字母表中的字符。Base64 module在Python中完成任务。
base64.b64decode()
函数接受一个字节字符串作为参数。在Python 2中,它的意思是:str
。在Python 3中,它的意思是:bytes
。所以如果你有一个str
,比如在Python 2中,您可以
因为
s
已经是ASCII格式。 在Python 3中,首先需要用ASCII编码,所以必须:顺便说一下,这将返回一个} 以获得从这些字节解包数据的工具。
bytes
对象,所以如何处理这些字节真的取决于您。也许这是我的浮动,但也许你应该尝试将其解码为ASCII:) 然而,在Python 2中,它只是一个str
。无论如何,请查看^{因此,如果需要在Python 2和3上运行代码,请使用最后一个。要确保最后有Unicode(如果要从base64解码文本),必须对其进行解码:
在Python 2上,
encode('ascii')
不会有效地执行任何操作,因为它应用于str
。因此,它将首先执行隐式转换到Unicode,然后执行所需的操作(将其转换回ASCII)。decode('ascii')
将在Python 2上返回一个unicode
对象。相关问题 更多 >
编程相关推荐