George Sakkis wrote:
I have a situation where one class can be customized with several
orthogonal options. Currently this is implemented with (multiple)
inheritance but this leads to combinatorial explosion of subclasses as
more orthogonal features are added. Naturally, the decorator pattern
[1] comes to mind (not to be confused with the the Python meaning of
the term "decorator").

However, there is a twist. In the standard decorator pattern, the
decorator accepts the object to be decorated and adds extra
functionality or modifies the object's behavior by overriding one or
more methods. It does not affect how the object is created, it takes
it as is. My multiple inheritance classes though play a double role:
not only they override one or more regular methods, but they may
override __init__ as well. Here's a toy example:


I don't know if it will map to your actual problem, but here's a variation of your toy code. I was thinking the Strategy pattern, different classes have different initialisation strategies? But then you could end up with as many Strategy classes as subclasses, I don't know. (Also in vaguely similar territory - http://bazaar.launchpad.net/~grflanagan/python-rattlebag/trunk/annotate/head:/src/template.py
)


class MetaBase(type):

    def __init__(cls, name, bases, data):
        cls.strategies = []
        cls.prefixes = []
        for base in bases:
            print base
            if hasattr(base, 'strategy'):
                cls.strategies.append(base.strategy)
            if hasattr(base, 'prefix'):
                cls.prefixes.append(base.prefix)
        super(MetaBase, cls).__init__(name, bases, data)

class Joinable(object):
    __metaclass__ = MetaBase
    strategy = list
    prefix = ''

    def __init__(self, words):
        self._words = words
        for strategy in self.strategies:
            self._words = strategy(self._words)

    def join(self, delim=','):
        return '%s %s' % (' '.join(self.prefixes), delim.join(self._words))

class Sorted(Joinable):
    strategy = sorted
    prefix = '[sorted]'

class Reversed(Joinable):
    strategy = reversed
    prefix = '[reversed]'

class SortedReversed(Sorted, Reversed):
    pass

class ReversedSorted(Reversed, Sorted):
    pass

if __name__ == '__main__':
    words = 'this is a test'.split()
    print SortedReversed(words).join()
    print ReversedSorted(words).join()

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to