当前位置: 代码迷 >> python >> 使用pre和post方法调用来装饰请求模块调用
  详细解决方案

使用pre和post方法调用来装饰请求模块调用

热度:81   发布时间:2023-07-14 08:58:52.0

我有一个名为Client的类,它使用requests模块与服务进行交互。 它有如下方法:

def get_resource(self, url, headers):
    response = requests.get(url, headers, auth=self.auth)
    return response

现在我想在每次调用requests模块之前和之后调用一些方法。 就像是:

def get_resource(self, url, headers):
    self.add_request_header(headers)
    response = requests.get(url, headers, auth=self.auth)
    self.process_response_headers()
    return response

我无法在不重写所有Client方法的情况下找到解决方法。 最直接的方法是将对请求模块的调用更改为对self的调用,并将调用添加到那里的方法。

def get_resource(self, url, headers):
    response = self.__get(url, headers, auth=self.auth)
    return response

def __get(self, headers, auth):
    self.add_request_header(headers)
    response = requests.get(url, headers, auth=self.auth)
    self.process_response_headers()
    return response

但这需要我更改请求模块的所有呼叫站点和重复功能。 我试图使用装饰器将这些方法调用添加到请求模块函数中,但是如何将自己传递给装饰器则陷入困境。

我确信在Python中有一种优雅的方法可以做到这一点。

你可以使用猴子补丁。 阅读本文:

    import requests
    def get(self, url, params=None, **kwargs):
        self.add_request_header(self.headers)
        response = requests.get(url, self.headers, auth=self.auth)
        self.process_response_headers()
    setattr(requests.Session, 'get', requests.Session.get)
    s = requests.Session()

我认为在这种情况下,装饰器不会听起来那么好,OOP是解决问题的更好方法。 您可以使用基类Client:

class Client(object):
    def __init__(self, auth):
        self.auth = auth

    def add_request_header(self, headers):
        pass

    def process_response_headers(self):
        pass

    def get_resource(self, url, headers):
        self.add_request_header(headers)
        response = requests.get(url, headers, auth=self.auth)
        self.process_response_headers()
        return response

并使用add_request_header和/或process_response_headers其他实现创建另一个子类,以便稍后您只需要实例化更适合您的案例的类

  相关解决方案