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