Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: How do you intercept a method call to change function parameters?

Tags:

python

What I am trying to do is write a wrapper around another module so that I can transform the parameters that are being passed to the methods of the other module. That was fairly confusing, so here is an example:

import somemodule

class Wrapper:
    def __init__(self):
        self.transforms = {}
        self.transforms["t"] = "test"

    # This next function is the one I want to exist
    # Please understand the lines below will not compile and are not real code
    def __intercept__(self, item, *args, **kwargs):
        if "t" in args:
            args[args.index("t")] = self.transforms["t"]
        return somemodule.item(*args, **kwargs)

The goal is to allow users of the wrapper class to make simplified calls to the underlying module without having to rewrite all of the functions in the module. So in this case if somemodule had a function called print_uppercase then the user could do

w = Wrapper()
w.print_uppercase("t")

and get the output

TEST

I believe the answer lies in __getattr__ but I'm not totally sure how to use it for this application.

like image 284
Nick Chapman Avatar asked Oct 23 '25 23:10

Nick Chapman


1 Answers

__getattr__ combined with defining a function on the fly should work:

# somemodule

def print_uppercase(x):
    print(x.upper())

Now:

from functools import wraps

import somemodule

class Wrapper:
    def __init__(self):
        self.transforms = {}
        self.transforms["t"] = "test"

    def __getattr__(self, attr):
        func = getattr(somemodule, attr)
        @wraps(func)
        def _wrapped(*args, **kwargs):
            if "t" in args:
                args = list(args)
                args[args.index("t")] = self.transforms["t"]
            return func(*args, **kwargs)
        return _wrapped


w = Wrapper()
w.print_uppercase('Hello')
w.print_uppercase('t')

Output:

HELLO
TEST
like image 197
Mike Müller Avatar answered Oct 25 '25 13:10

Mike Müller



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!