2

Say you have class Foo which has 4 methods and class FooDecorator. From those 4 methods, FooDecorator only needs to decorate one method.

Is it ok from a pythonic/OO design point of view to use __getattr__ for forwarding the requests to the decorated instance? This would basically remove a lot of boilerplate code in the deocrator class.

Example:

class Foo(object):

    def method_1(self):
        return some, stuff

    def method_2(self):
        return some, stuff

    def method_3(self):
        return some, stuff

    def method_4(self):
        return some, stuff

class FooClassicDecorator(object):
    def __init__(self, foo_instance):
        self._foo_instance = foo_instance

    def method_1(self):
        returned = self._foo_instance.method_1()
        return decorate_result(returned)

    def method_2(self):
        return self._foo_instance.method_2()

    def method_3(self):
        return self._foo_instance.method_3()

    def method_4(self):
        return self._foo_instance.method_4()

class FooGetattrDecorator(ojbect):
    def __init__(self, foo_instance):
        self._foo_instance = foo_instance

    def __getattr__(self, attr_name):
        return getattr(self._foo_instance, attr_name)

    def method_1(self):
        returned = self._foo_instance.method_1()
        return decorate_result(returned)

Which do you find more elegant? FooClassicDecorator or FooGetattrDecorator ?

Ioan Alexandru Cucu
  • 11,981
  • 6
  • 37
  • 39
  • I don't think I'd use either. I'd just subclass `Foo` and override the one method. – Aya Jun 25 '13 at 14:25
  • @Aya Yea... but the point of the decorator is that you should be able to decorate already existing instances. Taking the example from wikipedia you should be able to do Sprinkles(Milk(Whip(SimpleCoffe()))) or have a latte by doing Milk(Milk(SimpleCoffe())). The number of combinations or the order of applyting the decorators can be huge. – Ioan Alexandru Cucu Jun 25 '13 at 18:00
  • Why don't you just use a Python [decorator](http://www.python.org/dev/peps/pep-0318/) then? – Aya Jun 25 '13 at 18:04
  • Pass. I can't really envision a concrete example of when I'd want to use this pattern in Python. Due to Python's dynamic nature, many design patterns for other languages end up becoming anti-patterns in Python. – Aya Jun 25 '13 at 21:52
  • @Aya I agree... But not for this particular case. The same use cases in which the pattern is useful in static languages would also be useful in dynamic languages. – Ioan Alexandru Cucu Jun 25 '13 at 23:38

1 Answers1

1

I found this other question which is quite similar. The highest voted and accepted answer seems to be quite similar with my FooGetattrDecorator

Implementing the decorator pattern in Python

Closing this and also marking as duplicate.

Community
  • 1
  • 1
Ioan Alexandru Cucu
  • 11,981
  • 6
  • 37
  • 39