11

我需要猴子补丁请求的响应类(版本 1.0.4,截至本问题的当前版本),以添加其他方法。

我有这个代码:

import requests

class Response(requests.models.Response):
    def hmm(self):
        return 'ok'

requests.models.Response = Response

r = requests.get('http://bbc.co.uk')

print r

当原始响应调用 super() 时失败 - https://github.com/kennethreitz/requests/blob/master/requests/models.py#L391

我认为这是因为它变得混乱,因为我已经更换了班级,我觉得我在做一些愚蠢的事情,有什么想法吗?提前致谢。

4

3 回答 3

12

你最好将你的函数直接添加到类中:

def hmm(self):
    return 'ok'
requests.models.Response.hmm = hmm

这工作得很好:

>>> import requests
>>> def hmm(self):
...     return 'ok'
... 
>>> requests.models.Response.hmm = hmm
>>> r = requests.get('http://bbc.co.uk')
>>> print r
<Response [200]>
>>> r.hmm()
'ok'
>>> requests.__version__
'1.0.4'
于 2013-01-04T14:34:28.323 回答
5

我认为你不能像那样对那种类型进行猴子补丁。导入时requests,所有这些模块都被初始化。并且随着整个库from xy import Request一遍又一遍地使用,它将对实际类型有一个精确的引用。只有在那之后,您才替换模型模块中的响应类型,因此只有后续的导入会受到影响。

除非您检查所有模块并用您的新类型手动替换它们的响应引用,否则它们仍将使用原始的,使您的补丁无用。

相反,您应该保留原始类型,但直接扩展它,正如 Martijn 建议的那样。

于 2013-01-04T14:37:21.283 回答
1

只是使用的快速修复setattr,但它有点难看(但在语义上等同于@Martijn answer):

def hmm(self):
    return 'OK - %s' % self.status_code

setattr(requests.models.Response, 'hmm', hmm)

r = requests.get('http://bbc.co.uk')
print r.hmm()
# prints 
# OK - 200
于 2013-01-04T14:40:25.023 回答