Python: Monkeypatching 一个对象的方法

Python: Monkeypatching a method of an object

我正在通过请求会话 class 在 python 中点击 API。我正在使用 requests.Session().

进行 GET & POST 方法调用

在每次调用(GET/POST)失败时,我想通知另一个进程。我可以通过创建一个实用方法来做到这一点,如下所示:

s = request.Session()
def post():
    try:
        s.post(URL,data,headers)
    except:
        notify_another_process()

并调用此方法而不是直接调用 requests.Session().post

但是,我想将此代码修改为 requests.Session().post 并希望在 requests.Session().post 方法调用本身中通知其他进程的附加功能。我怎样才能做到这一点?

编辑 1:

requests.Session() 的 post 方法具有以下签名:

def post(self, url, data=None, json=None, **kwargs):
    return self.request('POST', url, data=data, json=json, **kwargs)

如果我以某种方式尝试自定义 post,如下所示:

def post_new(self, url, data=None, json=None, **kwargs):
    try:
        s.post(url,data, json,kwargs)
    except:
        notify_another_process()

并按如下方式打补丁:

requests.post = post_new

这不是一个很好的 monkeypatching,因为我没有使用 self,而是在 session.post.

中使用 session's object

这应该可以解决这个问题。您基本上用不同的名称保存旧函数并将您的函数作为默认函数 post.

setattr(requests, 'old_post', requests.post)

def post(url, data=None, json=None, **kwargs):
    try:
        requests.old_post(url, data, json, kwargs)
    except:
        notify_another_process()

setattr(requests, 'post', post)

你快到了,但你应该使用 self 参数

def post_new(self, url, data=None, json=None, **kwargs):
    try:
        return self.request('POST', url, data=data, json=json, **kwargs)
    except:
        notify_another_process()

然后设置post函数为post_new

requests.post = post_new

这是对我有用的答案。它的灵感来自 Siddharth & lafferc 两者提到的答案。这是他们俩都提到的。

>>> import requests
>>> def post(self, url, data=None, json=None, **kwargs):
...     try:
...         raise Exception()
...     except:
...         print "notifying another process"
... 
>>> setattr(requests.Session, 'post_old', requests.Session.post)
>>> setattr(requests.Session, 'post', post)
>>> s = requests.Session()
>>> s.post("url")
notifying another process