首页 > 解决方案 > 无法在 b64 中编码:需要类似字节的对象而不是“str”

问题描述

我正在尝试将 dict 转换为特殊的查询字符串。

该代码适用于 python2 但不适用于 3

例如,使用此输入:

{'retry': '0', 'locator': 'gamespy.com', 'datetime': '20201114223555'}

我想得到这个输出:

retry=MA**&locator=Z2FtZXNweS5jb20*&datetime=MjAyMDExMTQyMjM1NTU\r\n

我的 dict_to_qs :

def dict_to_qs(d):
    ret = {k: base64.b64encode(v).replace("=", "*") for k, v in d.items()}
    return "&".join("{!s}={!s}".format(k, v) for k, v in ret.items()) + "\r\n"

但我有这个错误:

  File "/var/www/server/other/utils.py", line 443, in dict_to_qs
        ret = {k: base64.b64encode(v).replace("=", "*") for k, v in d.items()}
      File "/var/www/server/other/utils.py", line 443, in <dictcomp>
        ret = {k: base64.b64encode(v).replace("=", "*") for k, v in d.items()}
      File "/usr/lib/python3.7/base64.py", line 58, in b64encode
        encoded = binascii.b2a_base64(s, newline=False)
    TypeError: a bytes-like object is required, not 'str'

标签: pythonpython-3.xpython-2.7base64byte

解决方案


问题是它b64encode需要一个类似字节的对象,并且 replace必须在字符串上调用。在 Python 3 中,这两种类型不像在 Python 2 中那样隐式转换,因此必须显式转换。您可以使用str.encode()andstr.decode()方法。

下面的代码在语义上应该等同于您的 Python 2 示例。

def dict_to_qs(d):
    ret = {k: base64.b64encode(str.encode(v)).decode().replace("=", "*") for k, v in d.items()}
    return "&".join("{!s}={!s}".format(k, v) for k, v in ret.items()) + "\r\n"

输出:retry=MA**&locator=Z2FtZXNweS5jb20*&datetime=MjAyMDExMTQyMjM1NTU*\r\n


推荐阅读