【问题标题】:LookupError: 'base64' is not a text encoding when upgrading code from Python2 to Python3LookupError:将代码从 Python2 升级到 Python3 时,'base64' 不是文本编码
【发布时间】: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


    【解决方案1】:

    在 python2 中,bytesstr 是等价的,但不再是 python3。

    '%s:%s' % (self._username, self._password) 你会得到一个str (例如'test:test')。 base64.b64encode 方法(及相关方法) 需要bytes,这就是为什么你必须先编码。

    base64.b64encode 将返回一个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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-13
      • 2020-10-11
      • 1970-01-01
      • 2017-01-24
      • 1970-01-01
      • 2021-09-06
      • 2021-07-10
      • 1970-01-01
      相关资源
      最近更新 更多