Calling __init__ for all mixins

Martin Maney maney at pobox.com
Wed Aug 18 17:05:57 CEST 2004


I've been to the cookbook (both forms, since they're sometimes usefully
different), but that gave rise to more questions than answers.  Heck,
let me pull some of them up while I'm at it.

Martelli gives the recipie (5.3 on paper) "Calling a Superclass
__init__ Method if it Exists" where he seems to say that this:

class NewStyleOnly(A, B, C):
	def __init__(self):
		super(NewStyleOnly, self).__init__()

is the New Class Speak equivalent of

class Classic(A, B, C):
	def __init__(self):
		for base in self.__class__.__bases__:
			if hasattr(base, '__init__'):
				base.__init__(self)

but when I tried a simple test case (base classes just print a tracer
when called), Martelli's NewStyleOnly only invoked A.__init__, as it
was the first base class in the base list as written with an __init__
implemented.  These seem to me to be very different.

In the completely different category of things that make you scratch
your head, online recipie 146462 suggests code that seems to be a
candidate for best gratuitous use of 'continue'.  Or is there some
subtle reason to prefer

for x in something:
	if somecondition:
		do_one_thing()
	else:
		continue
	do_the_other_thing()

rather than the simpler and clearer

for x in something:
        if somecondition:
                do_one_thing()
                do_the_other_thing()

or maybe even push the condition up into a comprehension in the for
statement.  Yeah, it sometimes makes for long lines, but it also makes
it perfectly clear that you aren't doing *anything* with the filtered
elements.  One thing I always thought C got stunningly right was its
for construct.  How better to summarize a loop than to give its initial
conditions, loop invariant test, and fixup for next code all together
inone place?  Well, given that you don't have lists and manage to make
the vast majority of loops be simple iterations over lists...  :-)

Yes, in retrospect maybe it would have been easier to have signed up
for ASPN and pointed this out in a comment, but I prefer not to
contribute to speedbumped sites like that both on principle, and as an
expression of essential laziness, and because there's a better audience
here anyway.  Wait, that's three reasons...


So the reason I was turning over these stones was that I'm working on a
subsystem where I want to compose working classes using multiple mixin
base classes to provide different implementations for separate parts of
the interface.  So far this is working quite nicely (1), but the
business of calling all the mixins' __init__ functions is a bit of a
nuisance.  Unfortunately, the solutions I've found (aside from
Martelli's NewStyleOnly which I'm sure was only accidentally implied to
be a solution to this problem) all seem little is any better than the
simple and obvious method of explicitly invoking each one.  I'm not
certain that I won't need to use that manual approach in the end, since
the current draft has a couple of arguments to one mixin, and it's not
clear I can eliminate them, but I would still be interested in any
suggestions for nicer solutions to the MI __init__ problem.


(1) the one nasty bit where a third mixin seems to want to provide a
few elements of what are otherwise two different mixin categories can
probably be subdued, if only by introducing the type of indirection
sometimes called "Strategy", though it's been a standard trick since
decades before design patterns were ever heard of.

-- 
Man's mind, once stretched by a new idea,
never regains its original dimensions.  -- Oliver Wendell Holmes



More information about the Python-list mailing list