3

I have an object whose primary value is in applying a given decorator to every function it inherits from its super class and providing a separate version of it. For reference the decorator is below:

def hierarchywrapper(func):
    def wrapper(self, *args, **kwargs):
        for key, value in self.hierarchy.items():
            try:
                result = getattr(value, func.__name__)(*args, **kwargs)
                if result and len(result):
                    return result
                else:
                    pass
            except:
                pass
        return None
    return wrapper

The super class of the object containing this decorator has quite a few functions and I would prefer not to have to write out stubs for every one of them. As you can tell, the contents of these functions aren't very important and just need stubs really.

Is there some way to define function stubs en masse? Alternately is there some way I could indicate that I just want to apply this decorator to every inherited function?

Slater Victoroff
  • 21,376
  • 21
  • 85
  • 144

1 Answers1

2

One way to do this would be to specialize the __getattribute__ method on your subclass:

def __getattribute__(self, name):
    attr = super(MySuperclass, self).__getattribute__(name)
    if callable(attr):
        return hierarchywrapper(attr)
    else:
        return attr

@eevee suggests an even more general approach by wrapping the parent object rather than subclassing it:

class CallableHierarchyWrapper(object):

    def __init__(self, wrapped_object):
        self.wrapped_object = wrapped_object

    def __getattribute__(self, name):
        attr = self.wrapped_object.__getattribute__(name)
        if callable(attr):
            return hierarchywrapper(attr)
        else:
            return attr
Peter DeGlopper
  • 36,326
  • 7
  • 90
  • 83
  • Oooh. I see! Great solution, just what I was looking for. – Slater Victoroff Oct 30 '13 at 21:02
  • better yet, wrap instead of subclassing, and this will work with any class :) also note that special methods do not trigger `__getattribute__`. – Eevee Oct 30 '13 at 21:02
  • 1
    @eevee - what would you wrap? I'm not disagreeing, I'm just not sure where you'd do that. – Peter DeGlopper Oct 30 '13 at 21:03
  • instead of `obj = Subclass()`, do `obj = Wrapper(Superclass())`. this wrapping doesn't seem to have anything to do with the actual state of the class, so no need to tangle into its inheritance hierarchy – Eevee Oct 30 '13 at 21:05
  • 1
    I see, and then keep the `Superclass` instance around as member data? Yeah, that would work too; I'll edit it in as an alternative. – Peter DeGlopper Oct 30 '13 at 21:06