[EMAIL PROTECTED] wrote: > On 13 Feb, 09:14, Peter Otten <[EMAIL PROTECTED]> wrote: >> [EMAIL PROTECTED] wrote: >> > Thanks both for suggestions. I still think that using inheritance is >> > somehow cleanest in this case (I always hear the mantra "avoid >> > multiple inheritance!", but this is one of the cases it seems to make >> > a lot of sense to me), but it's nice food for thought/code anyway. >> >> "Avoid inheritance" would be almost as justified :-) > > Why?
Well, what problems ocurring with class A: pass class B: pass class C(A, B): pass could be avoided by writing class A: pass class B(A): pass class C(B): pass instead? Classes have to be designed for subclassing, so essentially you get two interfaces, one for subclasses and one for client code instead of just the latter. A more relevant mantra governing inheritance is "Flat is better than nested". >> Problems that may arise with this case of multiple inheritance: >> >> - If you need initializers, ensure that they are all invoked > > Yes, I figured it out. This should be easy in this case. > >> - What would you do about name clashes? To avoid them your plugins need >> to know about each other. > > Yes, I know, but I can't see any simple solution to this (if you can, > please share it with me!). The cmd module works by interpreting any > method starting with "do_" as a command, so "do_blah" becomes the > "blah" command. If two people write a "do_blah" command, and both > plugins are used, I see no easy way to solve the issue (apart > rewriting a cmd module). > Perhaps there can be some previous sanity check in each modules dict > to see if there are obvious namespace clashings, and in this case > issue a warning. I don't know. > >> - State (instance attributes) is shared among all your plugins. Since you >> call all base classes Commands, Python's double-underscore hack won't >> work. > > What double-underscore hack are you referring to? (sigh, my python > limits are all arising...) I can call all base classes > PluginNameCommand, however, this wouldn't break the thing (I'm still > at the very early planning stage) and would maybe work. If you use attributes starting with two underscores inside a method, Python transparently prepends them with the class name. This allows to you to use the same variable name in two base classes and reduces coupling: >>> class A: ... def set_a(self, v): self.__value = v ... >>> class B: ... def set_b(self, v): self.__value = v ... >>> class C(A, B): pass ... >>> c = C() >>> c.set_a("alpha"); c.set_b("beta") >>> vars(c) {'_A__value': 'alpha', '_B__value': 'beta'} But if two classes with the same name use the "private" variable, the mechanism fails: >>> OldA = A >>> class A: ... def set_b(self, v): self.__value = v ... >>> class C(A, OldA): pass ... >>> c = C() >>> c.set_a("alpha"); c.set_b("beta") >>> vars(c) {'_A__value': 'beta'} Peter -- http://mail.python.org/mailman/listinfo/python-list