Search code examples
pythonloggingdecoratorproxy-classes

Simple logging object


I have some python module, which has a class ModuleClass and I can't modify that class.

Now, I want to be able to proxify the method calls and add certain logging features. I assume this should be done via forwarding object and the corresponding proxy (following Effective Java, Item 16).

The python pseudocode I came up with follows.

(Sorry, I'm really bad at python and I would appreciate if you could point out errors here).

# This is what I've got in my module and this code cannot be changed.
class ModuleClass(object):
    def method1(self):
        # Some implementation
        pass()
    def method2(self):
        # Some implementation
        pass()

# Simple forwarding proxy to avoid the situation described in Effective Java, I16

# However, in Java this class would usually be extending the interface, not
# inheriting 'ModuleClass' (I'm confused and don't know how to do the same
# in python).

class ForwardingModuleClass(ModuleClass):
    # 'proxifiedObject' is 
    def __init__(self, proxifiedObject):
        self.proxifiedObject = proxifiedObject

    # Overriding the first method
    def method1(self):
        return self.proxifiedObject.method1()

    # Same for method2...

class LoggingModuleClass(ForwardingModuleClass):
    # 'classThatActuallyDoesStuff' should be an instance of 'ModuleClass'.
    def __init__(self, classThatActuallyDoesStuff):
        # Sorry for my bad knowledge of python syntax, but
        # I assume I can initialize the superclass here using
        # the supplied 'ModuleClass' instance.
        super(classThatActuallyDoesStuff)

    # Overriding the first method.
    def method1(self):
        print("Yay! This 'method1' really logs something!")
        return super.method1()

    # Overriding the second method.
    def method2(self):
        print("Yay!!!! This 'method2' also does something cool!")
        return super.method2()

Now, I guess, properly written, this would work and I would have the logging proxy for my initial ModuleClass.

If there are errors or if this is not pythonish, please point it out.

Also, I suspect this can easily be done using decorators, but, unfortunately, I can't figure the appropriate way and I have no idea what might happen if ModuleClass already has some method decorators.

Could you help me here too?


Solution

  • If you really want a wrapper, then just write it, with no subclassing and intermediate classes.

    class LoggingFoo(object):
        def __init__(self, *args, **kwargs):
            self.obj = Foo(*args, **kwargs)
    
        def method1(self):
            # ...
            return self.obj.method1()
    
        def method2(self):
            # ...
            return self.obj.method2()