On Jun 16, 11:10 pm, Maric Michaud <[EMAIL PROTECTED]> wrote: > Le Monday 16 June 2008 20:35:22 George Sakkis, vous avez écrit : > > > > > 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: > > Yes, and it fails to implement the strategy pattern as well... which would > have solved the problem as it is intended exactly for this purpose.
As someone in another newsgroup demonstrated, it can be solved with a combination of strategy and decorator: http://tinyurl.com/5ulqh9 George -- http://mail.python.org/mailman/listinfo/python-list