David Masip
David Masip

Reputation: 2511

Add decorator to method from library class

I have a class that I cannot change (it comes from a library), which may look like

class Test(object):
    def __init__(self):
        pass

    def bar(self, x):
        return x

And I want to add a decorator to the bar method in Test, like the following, for instance:

from functools import wraps

def some_decorator(fn):
    @wraps(fn)
    def wrapped(*args, **kwargs):
        return "<b>" + fn(*args, **kwargs) + "</b>"
    return wrapped

By "adding" the decorator I mean to have a way to generate objects that have the bar method wrapped in some_decorator.

However, I cannot change the code in Test, which makes my problem harder. Is there an easy way to add a decorator in a method from a class that I cannot change in python?

Upvotes: 1

Views: 1244

Answers (2)

Arun Kaliraja Baskaran
Arun Kaliraja Baskaran

Reputation: 1086

If you dont want to modify the original class definition then you can achieve this with with simple inheritance itself instead of using decorators..

class Test(object):
    def __init__(self):
        pass

    def bar(self, x):
        print("In base bar..")
        return x

class DerivedTest(Test):
    def __init__(self):
        super().__init__()

    def bar(self,x):
        print("In derive's bar..")
        super().bar(x)

Now say when you execute:

dt=DerivedTest()
dt.bar(10)

The output will be

In derive's bar..
In base bar..

You can put whatever wrapper code you were intending to before and after the super() call..

Upvotes: 3

Cappocappo
Cappocappo

Reputation: 51

As you probably know the decorator is just a function which takes a function as an argument and returns a new function, thus you can do following nasty-hacky monkeypatching:

import your_library
your_library.Test.your_function = your_decorator(your_library.Test.your_function)

Upvotes: 5

Related Questions