4

Python requests 模块的文档对钩子说“如果回调函数返回一个值,则假定它是替换传入的数据。如果函数没有返回任何内容,则不会影响其他任何内容”

现在我试图从我的钩子函数中返回一个值(在我的例子中是 int),它会抛出一个异常。当返回值是一个没有为其定义 raw() 方法的对象时,这在所有情况下都是有效的。

这是一些代码

def hook(resp,**kwargs):
    print resp.url
    return 1

def main()
    s = requests.Session()
    s.hooks = {"response":hook}
    r = s.get("http://localhost/index.html")

这是一个例外:

http://localhost/index.html
Traceback (most recent call last):
 File "/home/talha/ws/test.py", line 85, in <module>
   main()
 File "/home/talha/ws/test.py", line 72, in main
   r = s.get("http://localhost/index.html")
 File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 347, in get
   return self.request('GET', url, **kwargs)
 File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 335, in request
   resp = self.send(prep, **send_kwargs)
 File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 446, in send
   extract_cookies_to_jar(self.cookies, request, r.raw)
 AttributeError: 'int' object has no attribute 'raw'

session.py @line 446 中的代码试图在 dispatch_hook 之后提取 cookie ..来自源

    # Response manipulation hooks
    r = dispatch_hook('response', hooks, r, **kwargs)

    # Persist cookies
    extract_cookies_to_jar(self.cookies, request, r.raw)

要么文档需要更改,要么需要重新处理处理。处理此问题的最佳方法是什么?

[更新]

根据评论,我尝试返回基础response对象。事实证明它也不能以这种方式使用,因为它的一些字段被初始化为None.

较新的代码:

def hook(resp, **kwargs):
    obj = requests.Response()
    return obj

现在抛出异常:

Traceback (most recent call last):
File "/home/talha/ws/test.py", line 88, in <module>
   main()
File "/home/talha/ws/test.py", line 75, in main
   r = s.get("http://localhost/index.html")
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 347, in get
   return self.request('GET', url, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 335, in request
   resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 446, in send
   extract_cookies_to_jar(self.cookies, request, r.raw)
File "/usr/lib/python2.7/site-packages/requests/cookies.py", line 108, in extract_cookies_to_jar
    res = MockResponse(response._original_response.msg)
AttributeError: 'NoneType' object has no attribute '_original_response'

似乎我将不得不实施一个完整的伪响应?

4

1 回答 1

3

如果回调函数返回一个值,则假定它是替换传入的数据。如果该函数没有返回任何内容,则不执行任何其他操作。

这意味着您返回的任何内容都将取代您传递的响应对象。

文档中没有任何内容表明您可以返回任何东西。你期望会发生什么?

如果您想返回具有不同数据的响应,请返回仍然像响应一样的东西。这意味着您要么需要子类化requests响应对象,要么实现提供相同 API 的东西:

from requests.models import Response

class MyIntResponse(Response):
    def __init__(self, integer):
        super(MyIntResponse, self).__init__()
        self._content_consumed = True
        self._content = integer

def hook(resp,**kwargs):
    print resp.url
    newresp = MyIntResponse(1)
    newresp.raw = resp.raw  # copy across original HTTP response object

您可能希望从原始响应中复制一些其他属性;检查有关Response对象具有哪些属性的文档。

于 2013-07-09T11:44:26.870 回答