【问题标题】:Decorating requests module calls with pre and post method calls使用 pre 和 post 方法调用装饰请求模块调用
【发布时间】:2019-02-21 11:17:23
【问题描述】:

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

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

现在我想在每次调用请求模块之前和之后调用一些方法。比如:

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 方法的方法。最直接的方法是将对 request 模块的调用更改为对 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

但这需要我更改所有调用站点并复制请求模块的功能。我尝试使用装饰器将这些方法调用添加到请求模块函数中,但不知道如何将 self 传递给装饰器。

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

【问题讨论】:

  • 您能否像您所说的卡住一样展示您使用装饰器的尝试?

标签: python python-3.x python-decorators


【解决方案1】:

您可以使用猴子补丁。 阅读:Python: Monkeypatching a method of an object

    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()

【讨论】:

  • 我认为问题在于 self 指的是 Session 对象,而 add_request_headerClient 上的一个方法
【解决方案2】:

我认为在这种情况下,装饰器不会像听起来那么好,而 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 的其他实现创建另一个子类,因此稍后您只需实例化更适合您的情况的类

【讨论】:

  • 这与我在寻找替代方案的问题中给出的解决方案有何不同?
  • @MvdD 看来我没有正确理解你的问题,你能举两个例子add_request_headerprocess_response_headers吗?
猜你喜欢
  • 1970-01-01
  • 2015-11-10
  • 2015-07-02
  • 2017-05-25
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-08
相关资源
最近更新 更多