首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么response.content可以读两遍而不能解码成json

为什么response.content可以读两遍而不能解码成json
EN

Stack Overflow用户
提问于 2015-08-26 12:08:57
回答 1查看 2.6K关注 0票数 1

我今天发现了一种奇怪的行为。我通过python请求库在google云消息传递中发送了一条消息。然后,我试图像这样解码对json的响应:

代码语言:javascript
运行
复制
response = requests.post(Message_Broker.host, data=json.dumps(payload), headers=headers)
response_results = json.loads(response.content)["results"]

它崩溃时有一个解码错误:

代码语言:javascript
运行
复制
response_results = json.loads(response.content)["results"]
  File "/usr/local/lib/python2.7/dist-packages/simplejson/__init__.py", line 505, in loads
    return _default_decoder.decode(s)
  File "/usr/local/lib/python2.7/dist-packages/simplejson/decoder.py", line 370, in decode
    obj, end = self.raw_decode(s)
  File "/usr/local/lib/python2.7/dist-packages/simplejson/decoder.py", line 400, in raw_decode
    return self.scan_once(s, idx=_w(s, idx).end())
JSONDecodeError: Expecting value: line 1 column 1 (char 0)

这发生在我的生产系统上,因此我添加了一些调试日志记录,以了解响应的实际内容如下:

代码语言:javascript
运行
复制
        logger.info("GCM-Response: " + str(response))
        logger.info("GCM-Response: " + response.content)
        logger.info("GCM-Response: " + str(response.headers))

现在实际发生了奇怪的行为。它被正确地记录并且不再抛出解码错误。

有人能解释一下我的行为吗?

我还检查了response.content实际上是什么:

代码语言:javascript
运行
复制
@property
    def content(self):
        """Content of the response, in bytes."""

        if self._content is False:
            # Read the contents.
            try:
                if self._content_consumed:
                    raise RuntimeError(
                        'The content for this response was already consumed')

                if self.status_code == 0:
                    self._content = None
                else:
                    self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()

            except AttributeError:
                self._content = None

        self._content_consumed = True
        # don't need to release the connection; that's been handled by urllib3
        # since we exhausted the data.
        return self._content

它是requests模型的一部分。不是一个实际的属性,而是可以通过@property装饰器访问。据我理解,第一次为日志读取内容时,_content_consumed标志被设置为True。因此,当我第二次为json解码读取它时,它实际上应该会引发运行时错误。

是否有一个解释,我只是在浏览请求文档时找不到?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-26 13:35:05

因此,当我第二次为json解码读取它时,它实际上应该会引发运行时错误。

不,它不会引发RuntimeError。当您第一次访问response.content时,它将将实际数据缓存到self._content中。在第二次访问(第三次、第四次等)中,if self._content is False:是错误的,因此您将获得缓存在self._content中的内容。

if self._content_consumed:检查很可能是内部断言,可以发现多次从套接字读取数据的尝试(这显然是一个错误)。

它不能被解码为JSON,因为您在响应体中没有接收到JSON,或者接收到了空体。可能是500次回复或者429次。如果不看到实际的反应,那是不可能说出来的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32226243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档