Question

The Twython module uses requests module internally.

I want to wrap/decorate request's requests.post(*k, **kw) method so everything Twython makes a request.post(...) call it will be transparently decorated/wrapped without interfering with the Twython module.

If I edited the requests codebase that'd be easy enough but I'm curious how to solve the general problem of adding a decorator to an already defined function/method.

import requests
def magic_wrapper_doodad(...)
...
...
requests.post = magic_wrapper_doodad(my_function, requests.post) # plz?

import Twython

# thanks to the above magic, requests.post is wrapped just as if it was defined like:
@decorator
def trace(f, *args, **kw):
    print("calling %s with args %s, %s" % (f.__name__, args, kw))
    return f(*args, **kw)

...
... #inside requests.py now:
@trace
def post(self, *args, **kw):
...

how do I write magic_wrapper_doodad() - or some alternative code - so I can decorate the code like this?

Was it helpful?

Solution

Decorator @ notation is just syntactic sugar for calling the decorator callable with the decorated function and replacing the decorated function with the result.

In other words, the following two examples are the exact same thing:

@yourdecorator
def a_function():
    pass

def b_function():
    pass
b_function = yourdecorator(b_function)

and the same applies to methods in class definitions.

Thus, you can simply decorate a class method by replacing the class method with the result of the decorator callable:

requests.post = my_function(requests.post)

This is the same as if you had written:

class requests(object):
    @my_function
    def post(self, *args):
        pass

Note that in your case requests is actually a module, not a class, but the same principles apply.

OTHER TIPS

Martijn Pieters' answer is the way to go if you need to decorate the requests function. I just thought I'd mention that requests does actually have a mechanism for hooks.

If you can do what you need to do with a hook instead, you should. It's cleaner than monkey patching.

What you are looking for might be done with aspect oriented programming.

Check this post from Stackoverflow and please let me know if it helps:

Do you use AOP (Aspect Oriented Programming) in production software?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top