473,561 Members | 3,340 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Calling __init__ for all mixins


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(NewStyleO nly, 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__(s elf)

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_th ing()

rather than the simpler and clearer

for x in something:
if somecondition:
do_one_thing()
do_the_other_th ing()

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
Jul 18 '05 #1
4 5129
Martin Maney wrote:
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(NewStyleO nly, 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__(s elf)

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.

<snipped unrelated problem>
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.


The new-style super mechanism might indeed solve your problem. In the
snippet that you mention, super(NewStyleO nly, self).__init__( ) would
only call A.__init__(). But A.__init__ should itself have a super call
of the form:

def __init__(self):
super(A, self).__init__( ) # A's super call

Now *that* will call B.__init__(), which should itself have a super call
of the form - you guessed it:

def __init__(self):
super(B, self).__init__( )

Which will call C.__init__(). And so on. Also note that super() will
work correctly in the case you had a class:

class AnotherClass(A, C):
def __init__(self):
super(NewStyleO nly, self).__init__( )

In this case, A's super call would call C.__init__(). Nice, huh?

This is the cooperative super call technique explained in the following
places:

http://www.python.org/2.2.3/descrintro.html#cooperation
http://www.cafepy.com/articles/pytho...hods/ch02.html

Any class wanting to participate in this technique must be new-style.

Cheers,
Shalabh

Jul 18 '05 #2
Martin Maney <ma***@pobox.co m> writes:
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(NewStyleO nly, 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__(s elf)

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.


Can you show your test code. I've found that you may need to ensure
all of your classes are cooperating in their use of super(), as in the
following:

mro.py:

class A(object):

def __init__(self):
print "A init"
super(A,self)._ _init__()

class B(object):

def __init__(self):
print "B init"
super(B,self)._ _init__()

class C(object):

def __init__(self):
print "C init"
super(C,self)._ _init__()
class Mix(A,B,C):

def __init__(self):
print "Mix init"
super(Mix,self) .__init__()
Python 2.2.3 (#42, May 30 2003, 18:12:08) [MSC 32 bit (Intel)] on win32
Type "help", "copyright" , "credits" or "license" for more information.
import mro
mro.Mix() Mix init
A init
B init
C init
<mro.Mix object at 0x0081EB48>


The new style MRO approach will only work if all of your objects are
new style classes and they all participate in the cooperative process
through the use of super(). Also, the precise MRO used has changed
between 2.2 and 2.3 but it shouldn't affect the above syntax.

I do think it's easy to find yourself skipping the call to object's
__init__ in classes since it doesn't necessarily do anything, but it's
those other super calls that provide the chance to iterate through the
inheritance hierarchy based on the initial call from the ultimate
subclass.

Guido has some info on the cooperative use of super in his 2.2
unification draft available at http://www.python.org/2.2.3/descrintro.html
and more info on the MRO change is at http://www.python.org/2.3/mro.html.

-- David
Jul 18 '05 #3
Shalabh Chaturvedi <sh*****@cafepy .com> wrote:
The new-style super mechanism might indeed solve your problem. In the
snippet that you mention, super(NewStyleO nly, self).__init__( ) would
only call A.__init__(). But A.__init__ should itself have a super call
of the form: def __init__(self):
super(A, self).__init__( ) # A's super call Now *that* will call B.__init__(), which should itself have a super call
I will be dipped in shit. So let me see... super(this_here _class,
self) can and will resolve to a class that is not in any sane meaning
of the word a super class of this_here_class , but rather a co-base of
it? This is either brilliant or pure crack. I'll have to ponder it
for a good long while.
http://www.python.org/2.2.3/descrintro.html#cooperation
Brilliant. Crack. Brilliant. Crack. ... Luminiferous Aether!

Was this chosen specifically to confuse anyone familiar with OO
terminology as used in other languages? <wink>
Any class wanting to participate in this technique must be new-style.


Which brings me back to the original motivation: any nice tricks for
doing this without NewSpeek classes? Maybe in a year or so I can get
all the production machines upgraded; for now, I have to write to the
subset that works across 2.1, 2.2, and, mostly just as a nod to that
future so far, 2.3 (I frankly haven't the time to do much worrying
about 2.4 yet, and don't expect to any time soon. It would be nice to
have only one or two machines to take care of and enough free time to
keep up to date with every release.)

--
Remember the refrain: We always build on the past;
the past always tries to stop us. Freedom is about stopping the past,
but we have lost that ideal. -- Lawrence Lessig
Jul 18 '05 #4
Martin Maney <ma***@pobox.co m> writes:
Shalabh Chaturvedi <sh*****@cafepy .com> wrote:
The new-style super mechanism might indeed solve your problem. In the
snippet that you mention, super(NewStyleO nly, self).__init__( ) would
only call A.__init__(). But A.__init__ should itself have a super call
of the form:
def __init__(self):
super(A, self).__init__( ) # A's super call

Now *that* will call B.__init__(), which should itself have a super call


I will be dipped in shit. So let me see... super(this_here _class,
self) can and will resolve to a class that is not in any sane meaning
of the word a super class of this_here_class , but rather a co-base of
it?


No. super(this_here _class, self) returns, well, a super() object that
when you look for an attribute on it acts a bit like `self.__class__ '
but only looks in classes later than `this_here_clas s' in the MRO.

Don't worry too much if that didn't make sense, but it's probably a
good idea to get the thought that super() returns a class out of your
head.
This is either brilliant or pure crack. I'll have to ponder it for
a good long while.
It's brilliant :-)

Cheers,
mwh

-- Well, as an American citizen I hope that the EU tells the MPAA
and RIAA to shove it where the Sun don't shine.

Actually they already did. Only first they bent over and dropped
their trousers. -- Shmuel (Seymour J.) Metz & Toni Lassila, asr
Jul 18 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
3703
by: Steven Bethard | last post by:
So when I'm writing a class and I define an __init__ method, I sometimes haven't called object.__init__, e.g.: class C(object): def __init__(self, x): self.x = x instead of class C(object):
14
6384
by: Axel Straschil | last post by:
Hello! Im working with new (object) classes and normaly call init of ther motherclass with callin super(...), workes fine. No, I've got a case with multiple inherance and want to ask if this is the right and common case to call init: class Mother(object): def __init__(self, param_mother): print 'Mother'
0
1068
by: Joshua Spoerri | last post by:
Anybody have an idea for how to do python mixins that don't down-call? Thanks ( Mixins from different vendors might use the same method names for unrelated features, but should continue to work sensibly. It's fine to have one mixin method override another in its "public" interface, but overriding a mixin's internal methods in its...
6
1905
by: Rob Cowie | last post by:
Hi all, Is there a simple way to call every method of an object from its __init__()? For example, given the following class, what would I replace the comment line in __init__() with to result in both methods being called? I understand that I could just call each method by name but I'm looking for a mechanism to avoid this.
4
3261
by: Noah | last post by:
Am I the only one that finds the super function to be confusing? I have a base class that inherits from object. In other words new style class: class foo (object): def __init__ (self, arg_A, arg_B): self.a = arg_A self.b = arg_B # Do I need to call __init__ on "object" base class?
16
1927
by: John Salerno | last post by:
Let's say I'm making a game and I have this base class: class Character(object): def __init__(self, name, stats): self.name = name self.strength = stats self.dexterity = stats self.intelligence = stats self.luck = stats
8
1755
by: kelin,zzf818 | last post by:
Hi, Today I read the following sentences, but I can not understand what does the __init__ method of a class do? __init__ is called immediately after an instance of the class is created. It would be tempting but incorrect to call this the constructor of the class. It's tempting, because it looks like a constructor (by convention, __init__...
25
2489
by: Erik Lind | last post by:
I'm new to Python, and OOP. I've read most of Mark Lutz's book and more online and can write simple modules, but I still don't get when __init__ needs to be used as opposed to creating a class instance by assignment. For some strange reason the literature seems to take this for granted. I'd appreciate any pointers or links that can help...
0
7647
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
1
7618
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7930
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6210
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5472
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3600
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2068
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1181
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
896
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.