Python: Monkeypatching a method of an object

巧了我就是萌 提交于 2019-12-22 09:49:55

问题


I'm hitting an API in python through requests' Session class. I'm making GET & POST method call using requests.Session().

On every call(GET/POST) failure, I want to notify another process. I can do this by creating a utility method as follows:

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

And call this method instead of requests.Session().post directly.

But, I want to monkeypatch this code to requests.Session().post and want the additional functionality of notifying the other process in the requests.Session().post method call itself. How can I achieve this?

EDIT 1 :

requests.Session()'s post method has the following signature:

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

If I somehow try to make my a custom post like the following:

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

and do a patch as follows:

requests.post = post_new

This isn't really a good monkeypatching because I'm not using self but session's object inside session.post.


回答1:


This should resolve this. You basically save the old function with different name and give your function as the default 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)



回答2:


You're almost there, but you should use the self argument

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

Then set the post function to post_new

requests.post = post_new



回答3:


This is the answer which worked for me. It is inspired by the answers mentioned by Siddharth & lafferc both. This is on top of what both of them mentioned.

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


来源:https://stackoverflow.com/questions/39850270/python-monkeypatching-a-method-of-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!