在我的用例中,很好的子类化Python响应类以启用诸如此类的功能
session = requests.Session()
response = session.get('/resource/')
response.custom_methods_on_response_object()
我希望能够在响应类上添加自定义方法。像.json
之类的东西很有用,但是如果我可以使用自定义方法将响应转换为更多可用的数据,它将更有用。
但是,如果不对会话对象进行过多的子类化,我将不清楚如何做到这一点。
答案 0 :(得分:0)
虽然不对响应进行子类化,但是使用挂钩可以实现类似的效果。相对于其他答案,此方法的优势在于,猴子补丁的作用范围仅限于响应(而不是整个类)。
https://requests.kennethreitz.org/en/master/user/advanced/#event-hooks
def record_hook(r, *args, **kwargs):
r.model = MyModel(**r.json())
return r
答案 1 :(得分:0)
要在请求中执行响应类的真正子类,可以执行以下操作。
from requests.models import Response
from requests.adapters import HTTPAdapter
from requests import Session
class CustomResponse(Response)
"""
Override response class with additional methods
"""
# add additional attrs
__attrs__ = Response.__attrs__ + ['method_name']
class CustomHttpAdapter(HTTPAdapter):
def build_response(self, req, resp):
response = CustomResponse()
# Fallback to None if there's no status_code, for whatever reason.
response.status_code = getattr(resp, 'status', None)
# Make headers case-insensitive.
response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {}))
# Set encoding.
response.encoding = get_encoding_from_headers(response.headers)
response.raw = resp
response.reason = response.raw.reason
if isinstance(req.url, bytes):
response.url = req.url.decode('utf-8')
else:
response.url = req.url
# Add new cookies from the server.
extract_cookies_to_jar(response.cookies, req, resp)
# Give the Response some context.
response.request = req
response.connection = self
return response
session = Session()
session.mount(
'https://', CustomHttpAdapter()
)
答案 2 :(得分:-1)
方法只是在对象上工作的函数(基本上是字典),因此,使用方法进行的任何操作都可以使用普通函数来完成。您唯一松动的是多态调度,但是您可能在这里不需要它。
例如,如果Response
还没有json
方法,则可以将其写为
def to_json(response):
return json.loads(response.text)
然后写reponse.json()
代替to_json(response)
。
现在,如果您真的想改用obj.method()
语法,则可以随时对Response
类进行修补:
import requests
from requests.models import Response
def revtext(response):
return response.text[::-1]
Response.revtext = revtext
r = requests.get("https://stackoverflow.com")
print(r.revtext())
但这通常不是一个好主意。