Search code examples
pythonwrapper

Creation of a class wrapper in Python


I would like to do the following: given an instance of a Base class create an object of a Wrapper class that has all the methods and attributes of the Base class + some additional functionality.

class Base:

    def __init__(self, *args, **kwargs):
         self.base_param_1 = ...
         # some stuff

    def base_method_1(self, *args, **kwargs):
         # some stuff

class Wrapper(...):

    def  __init__(self, cls_instance, *args, **kwargs):
        self.wrapper_param_1 = ...
        # some stuff

    def wrapper_method_1(self, *args, **kwargs):
        # some stuff

The use case is like the following:

wrapper_obj = Wrapper(Base(*base_args, **base_kwargs), *wrapper_args, *wrapper_kwargs)

The expected behavior is that one can access base_param_1, wrapper_param_1 and base_param_1, base_param_2.

It is important that the fields of the Base class are the same in Wrapper (no copying).

I've seen that new functionality can be added in this way Adding a Method to an Existing Object Instance, but this approach has caveats and is not recommended.

Inheritance seems not to be an option here, since I am an already constructed object and this Wrapper can take different classes, despite with common Base.

EDIT

It is also required that Wrapper object is identified as Base instance.


Solution

  • You can override __getattr__. That way, Wrapper specific attributes are looked up first, then the wrapped object's attributes are tried.

    class Wrapper:
        def  __init__(self, base_obj, *args, **kwargs):
            self.base_obj = base_obj
            # some stuff
    
        def wrapper_method(self):
            return "new stuff"
    
        def __getattr__(self, name):
            return getattr(self.base_obj, name)
            
    w = Wrapper("abc")
    w.wrapper_method()
    # 'new stuff'
    w.upper()
    # 'ABC'