我正在尝试延长requests.Response
,但我不确定该怎么做。
我想要的是扩展requests.Response
。我看到的问题是我必须创建一个全新的库分支,或者至少创建一个自定义适配器并为此实现自定义代码。
我目前正在将响应存储在我的新类的属性中,但这意味着我的自定义APIResponse
实际上并不像扩展的requests.Response
对象。
这是我目前的虚拟工作。
class APIResponse:
def __init__(self, req_response, formatted_json=None):
self._content = req_response._content
self._response = req_response
@property
def response(self):
return self._response
如上所述,我希望我的自定义类的行为类似于requests.Response
对象,并具有一些额外的功能。由于Response
对象是在非常低的级别生成的,即HTTPAdapter
库中的requests
模块,我也必须编写自定义适配器 - 而且,逻辑上也是自定义requests.Sessions
类,调用它。
这一切都让我相信我在这里错过了一些东西。
是否有一种合理的方式来扩展request.Response
个对象,而没有大量的代码?
我还尝试围绕一个实例化的Response
对象“包装”一个类,但它看起来非常hacky:
class APIResponse(Response):
__attrs__ = ['_content', 'status_code', 'headers', 'url', 'history',
'encoding', 'reason', 'cookies', 'elapsed', 'request',
'_formatted']
def __init__(self, req_response):
self._content = req_response._content
self._content_consumed = req_response._content_consumed
self.status_code = req_response.status_code
self.headers = req_response.headers
self.url = req_response.url
self.history = req_response.history
self.encoding = req_response.encoding
self.reason = req_response.reason
self.cookies = req_response.cookies
self.elapsed = req_response.elapsed
self.request = req_response.request
答案 0 :(得分:2)
如果您不介意影响requests
的其他代码(在同一解释器中),则可以猴子修补Response
类:
def patched_func(self, rvalue):
return rvalue
requests.Response.patched_func = patched_func
resp = requests.get("https://httpbin.org/get")
resp.patched_func("Another value")
# => "Another value"
答案 1 :(得分:1)
在看到“hacky”时首先想到的是它具有工作的优势。
但是,您可能会忘记要使用的方法所需的某些属性:为什么不简单地遍历__dict__属性来创建包装器?
它的外观如下:
class APIResponse(Response):
def __init__(self, req_response):
for k, v in req_response.__dict__.items():
self.__dict__[k] = v
它使代码更紧凑,但我必须承认它仍然非常hacky。
答案 2 :(得分:0)
我知道我参加聚会迟到了,但我自己也在考虑同样的事情,并认为我会分享我的解决方案。
requests.Response 类没有以通常的方式实例化,创建一个空实例,然后使用 setter 方法应用状态。
import requests
class MyResponseSubClass(requests.Response):
def __init__(self, response: requests.Response):
self.__setstate__(response.__getstate__())
pass
r = requests.post('https://httpbin.org/post', data={'key': 'value'})
my_response = MyResponseSubClass(r)
print(my_response.url, my_response.status_code, my_response.reason)
我创建了一个扩展请求子类的子类,然后我可以将响应对象传递给该类。它获取该响应对象的状态,然后将该状态应用于响应子类的新实例化子类。