On Jun 16, 1:49 pm, Gerard flanagan <[EMAIL PROTECTED]> wrote: > 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/annota... > ) > > 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()
This doesn't solve the original problem, the combinatorial explosion of empty subclasses. At the end of the day, I'd like a solution that uses a (mostly) flat, single-inheritance, hierarchy, allowing the client say: j = Joinable(words) if sort: j = Sorted(j) if reverse: j = Reversed(j) ... print j.join() George -- http://mail.python.org/mailman/listinfo/python-list