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 中,bytesstr 是等价的,但不再与 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()