首页 > 解决方案 > json.loads(string) 在尝试将字符串转换为字典时抛出 json.decoder.JSONDecodeError

问题描述


我正在使用该requests库进行 api 调用。然后将 json 响应格式化为字符串,并作为结果的一部分发送到我的服务器,如代码片段所示:

def get_and_send(url, method):
     resp = requests.request(url=url, method=method, **kwargs)
     result = f'{{ "status_code":{resp.status_code}, "content":{resp.json()} }}'
     send_to_server(result)

我打算将此结果从服务器上的字符串结果转换回字典对象。
我遇到的问题是,当我使用json.loads(result)将字符串转换为字典对象时,它会引发以下错误

Exception in thread Thread-2: Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
File "/home/adipster/PycharmProjects/ScriptBackbone/ts_server/agent_thread.py", line 39, in run
    resp_data = self._task_formatter.format_response(response) # Formats the response
File "/home/adipster/PycharmProjects/ScriptBackbone/utils/task_formatter.py", line 26, in format_response
    response = self.get_dict_response(response.decode().strip())
File "/home/adipster/PycharmProjects/ScriptBackbone/utils/task_formatter.py", line 36, in get_dict_response
    raise exp
File "/home/adipster/PycharmProjects/ScriptBackbone/utils/task_formatter.py", line 34, in get_dict_response
    return json.loads(response)
File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.6/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx) json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 32 (char 31)

我知道该错误是因为我的所有键都必须用双引号resp.json()引起来,而格式化为字符串时则不然。请有人帮助我如何确保我的字典对象的所有键都在双引号中?或者任何其他替代方案都将受到欢迎。谢谢

标签: pythonjson

解决方案


正如您所指出的,问题在于,如果您只是进行字符串插值(f例如,使用 -string),则 JSON 对象中字符串的引号将是单引号,但 JSON 格式需要双引号。

要解决此问题,您可以使用json.dumps它获取 JSON 对象(在 Python 中)并将其转换为格式正确的 JSON 字符串。感谢 Charles Duffy 进行编辑:您可以f完全避免使用 -string,只需将整个result_data对象创建为字典,然后使用json.dumps.

例如:

import json

def get_and_send(url, method):
    resp = requests.request(url=url, method=method, **kwargs)
    result_data = {
        "status_code": resp.status_code,
        "content": resp.json(),
    }
    result = json.dumps(result_data)
    send_to_server(result)

推荐阅读