Mar*_*cin 9 python base64 character-encoding unicode-string python-unicode
我已经使用从web服务检索的unicode字符串requests模块,它包含一个二进制文件的字节(PCL,因为它发生).其中一个字节的值为248,尝试对其进行base64编码会导致以下错误:
In [68]: base64.b64encode(response_dict['content']+'\n')
---------------------------------------------------------------------------
UnicodeEncodeError Traceback (most recent call last)
C:\...\<ipython-input-68-8c1f1913eb52> in <module>()
----> 1 base64.b64encode(response_dict['content']+'\n')
C:\Python27\Lib\base64.pyc in b64encode(s, altchars)
51 """
52 # Strip off the trailing newline
---> 53 encoded = binascii.b2a_base64(s)[:-1]
54 if altchars is not None:
55 return _translate(encoded, {'+': altchars[0], '/': altchars[1]})
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf8' in position 272: ordinal not in range(128)
In [69]: response_dict['content'].encode('base64')
---------------------------------------------------------------------------
UnicodeEncodeError Traceback (most recent call last)
C:\...\<ipython-input-69-7fd349f35f04> in <module>()
----> 1 response_dict['content'].encode('base64')
C:\...\base64_codec.pyc in base64_encode(input, errors)
22 """
23 assert errors == 'strict'
---> 24 output = base64.encodestring(input)
25 return (output, len(input))
26
C:\Python27\Lib\base64.pyc in encodestring(s)
313 for i in range(0, len(s), MAXBINSIZE):
314 chunk = s[i : i + MAXBINSIZE]
--> 315 pieces.append(binascii.b2a_base64(chunk))
316 return "".join(pieces)
317
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf8' in position 44: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
我发现这有点令人惊讶,因为248在无符号字节的范围内(并且可以保存在字节字符串中),但我真正的问题是:对这个字符串进行编码的最佳或正确方法是什么?
我目前的解决方法是:
In [74]: byte_string = ''.join(map(compose(chr, ord), response_dict['content']))
In [75]: byte_string[272]
Out[75]: '\xf8'
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常,结果byte_string是能够base64编码,但似乎应该有一个更好的方法.在那儿?
Cam*_*ron 18
你有一个unicode你想要base64编码的字符串.问题是b64encode()只适用于字节而不是字符.因此,您需要将unicode字符串(这是一系列抽象的Unicode代码点)转换为字节字符串.
将抽象Unicode字符串映射到具体的字节序列称为编码.Python支持多种编码; 我建议广泛使用的UTF-8编码:
byte_string = response_dict['content'].encode('utf-8')
Run Code Online (Sandbox Code Playgroud)
请注意,无论谁解码字节,还需要知道使用哪种编码unicode通过补充decode()函数获取字符串:
# Decode
decoded = byte_string.decode('utf-8')
Run Code Online (Sandbox Code Playgroud)
学习更多关于Unicode和编码的一个很好的起点是Python文档,以及Joel Spolsky 撰写的这篇文章.
小智 5
我建议在base64编码之前首先将它编码为类似UTF-8的东西:
In [12]: my_unicode = u'\xf8'
In [13]: my_utf8 = my_unicode.encode('utf-8')
In [15]: base64.b64encode(my_utf8)
Out[15]: 'w7g='
Run Code Online (Sandbox Code Playgroud)
由于您正在使用二进制数据,因此我不确定使用 utf-8 编码是否是一个好主意。我想这取决于您打算如何使用 base64 编码表示。我认为如果您可以将数据作为字节字符串而不是 unicode 字符串检索,可能会更好。我从未使用过 requests 库,但浏览文档表明这是可能的。有些部分讨论“二进制响应内容”和“原始响应内容”。