尝试将字符串转换为字典时,json.loads(string)会引发json.decoder.JSONDecodeError

时间:2019-03-10 23:46:22

标签: python json


我正在使用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()格式化为字符串时则不是这种情况。 请有人帮助我如何确保字典对象的所有键都用双引号引起来吗? 或任何其他替代方法都将受到欢迎。谢谢

1 个答案:

答案 0 :(得分:5)

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

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