【发布时间】:2019-08-28 12:59:49
【问题描述】:
我有一段 Python2 代码,我想升级到 Python3。它是一个与 API 通信的 Cinder 存储驱动程序。
我可以自己或在 2to3 的帮助下“转换”大部分代码。我不是程序员,但愿意学习。我被以下代码卡住了:
def _create_request(self, request_d, param_list):
"""Creates urllib.Request object."""
if not self._username or not self._password:
raise ValueError("Invalid username/password combination")
auth = ('%s:%s' % (self._username,
self._password)).encode('base64')[:-1]
headers = {'Content-Type': 'application/json',
'Authorization': 'Basic %s' % (auth,)}
url = self.get_url() + request_d
LOG.debug('url : %s', url)
LOG.debug('param list : %s', param_list)
return urllib.request.Request(url, param_list, headers)
特别是这部分:
auth = ('%s:%s' % (self._username,
self._password)).encode('base64')[:-1]
这给了我以下错误:
LookupError: 'base64' is not a text encoding; use codecs.encode() to handle arbitrary codecs
我尝试了一些选项,例如 base64.b64encode,但缺乏正确转换它的知识。请注意,它是一个要进行 base64 编码的字符串。
这是我最好的选择:
import base64
auth = base64.b64encode(('%s:%s' % (self._username, self._password)).encode('ascii'))
这是正确的吗?如果没有,什么是好的方法?
更新#1: 我在这段代码之外尝试了一些测试,我越来越接近了:
python2
>>> _username = 'test'
>>> _password = 'test'
>>> auth = ('%s:%s' % (_username, _password)).encode('base64')[:-1]
>>> print (auth)
dGVzdDp0ZXN0
python3
>>> import base64
>>> _username = 'test'
>>> _password = 'test'
>>> auth = base64.b64encode(('%s:%s' % (_username,
_password)).encode('ascii'))
>>> print (auth)
b'dGVzdDp0ZXN0'
如您所见,根据 Python2 的输出,所需的输出尚未与 Python3 代码的输出匹配。
更新 #2: 我找到了一个有效的解决方案,代码如下:
import base64
auth = base64.urlsafe_b64encode(('%s:%s' % (self._username, self._password)).encode('utf-8'))
authstr = str(auth, "utf-8")
我开始伤害自己了。输出是一个str,应该是字节...
【问题讨论】:
标签: python-3.x base64 python-2to3