Search code examples
pythonooppython-class

Log common method among classes in python


I am importing several classes from a library with a common method, like

class BarClass1:
    
    def __init__(self):
        pass        

    def bar(self, x):
        return x + 1

class BarClass2:
    
    def __init__(self):
        pass        

    def bar(self, x):
        return x + 2


class BarClass3:
    
    def __init__(self):
        pass        

    def bar(self, x):
        return x + 3

I want to add logging to the bar method of each class, and for that purpose I create children for these classes in the following way:


def log_something(x):
    print(f'input is {x}')

class DerivedBarClass1(BarClass1):
    
    def __init__(self):
        super().__init__()   

    def bar(self, x):
        log_something(x)
        return super().bar()

class DerivedBarClass2(BarClass2):
    
    def __init__(self):
        super().__init__()   

    def bar(self, x):
        log_something(x)
        return super().bar()

class DerivedBarClass3(BarClass3):
    
    def __init__(self):
        super().__init__()   

    def bar(self, x):
        log_something(x)
        return super().bar()

I feel I am doing a lot of code repetition, is there a simpler way of doing this? My main constraint is not being able to modify the code in BarClass1, BarClass2 or BarClass3.


Solution

  • If you can't modify the code, you can always monkey-patch the classes...

    import functools
    def add_logging_single_arg(f): # maybe a better name...
        @functools.wraps(f)
        def wrapper(self, x):
            log_something(x)
            return f(x)
        return wrapper
    
    for klass in [BarClass1, BarClass2, BarClass3]:
        klass.bar = add_logging_single_arg(bar)