LookupError: 'base64' is not a text encoding when upgrading code from Python2 to Python3
LookupError: 'base64' is not a text encoding when upgrading code from Python2 to Python3
我有一段 Python2 代码,我想升级到 Python3。它是一个与 API.
通信的 Cinder 存储驱动程序
大部分代码我可以 'convert' 自己或在 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 并且应该是 bytes...
在 python2 中,bytes
和 str
是等价的,但不再与 python3。
从 '%s:%s' % (self._username, self._password)
你得到一个 str
(例如 'test:test'
)。 base64.b64encode
方法(及相关方法)
需要 bytes
,这就是您必须先编码的原因。
base64.b64encode
将 return 一个 bytes
值(例如 b'dGVzdDp0ZXN0'
)。如果你想
要返回到 str
,您必须使用 str(xyz, 'utf-8') 或
xyz.decode('utf-8').
此外,utf-8 是 str 编码和字节解码的默认设置。
import base64
auth = base64.urlsafe_b64encode(('%s:%s' % (self._username,
self._password)).encode()).decode()
我有一段 Python2 代码,我想升级到 Python3。它是一个与 API.
通信的 Cinder 存储驱动程序大部分代码我可以 'convert' 自己或在 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 并且应该是 bytes...
在 python2 中,bytes
和 str
是等价的,但不再与 python3。
从 '%s:%s' % (self._username, self._password)
你得到一个 str
(例如 'test:test'
)。 base64.b64encode
方法(及相关方法)
需要 bytes
,这就是您必须先编码的原因。
base64.b64encode
将 return 一个 bytes
值(例如 b'dGVzdDp0ZXN0'
)。如果你想
要返回到 str
,您必须使用 str(xyz, 'utf-8') 或
xyz.decode('utf-8').
此外,utf-8 是 str 编码和字节解码的默认设置。
import base64
auth = base64.urlsafe_b64encode(('%s:%s' % (self._username,
self._password)).encode()).decode()