inheritance problem with 2 cooperative methods

Dan Perl danperl at rogers.com
Thu Dec 2 22:00:59 CET 2004


Here is a problem I am having trouble with and I hope someone in this group 
will suggest a solution.  First, some code that works.  3 classes that are 
derived from each other (A->B->C), each one implementing only 2 methods, 
__init__ and setConfig.
-------------------------------------------------------
#!/usr/bin/python
class A (object):
   def __init__(self):
      super(A, self).__init__()
      self.x = 0
   def setConfig(self, config):
      self.x += config['x']

class B (A):
   def __init__(self):
      super(B, self).__init__()
      self.y = 0
   def setConfig(self, config):
      super(B, self).setConfig(config)
      self.y += config['y']

class C (B):
   def __init__(self):
      super(C, self).__init__()
      self.z = 0
   def setConfig(self, config):
      super(C, self).setConfig(config)
      self.z += config['z']

config = {'x':1, 'y':2, 'z':3}
alpha = A()
alpha.setConfig(config)
print alpha.x
beta = B()
beta.setConfig(config)
print beta.x, beta.y
beta.setConfig(config)
print beta.x, beta.y
gamma = C()
gamma.setConfig(config)
print gamma.x, gamma.y, gamma.z
gamma.setConfig(config)
print gamma.x, gamma.y, gamma.z
--------------------------------------------------

The output from that code is:
1
1 2
2 4
1 2 3
2 4 6

So far, so good!  But let's assume that I want to change the __init__ 
methods so that they take a configuration as an argument so the objects are 
created and configured in one step, like this:
alpha = A(config)

How can the code be changed to implement this?  It is tempting to modify the 
__init__ methods like this:
class A (object):
   def __init__(self, config):
      super(A, self).__init__(config)
      self.x = 0
      A.setConfig(self, config)

However, if implemented this way, the output is:
1
2 2
3 4
3 4 3
4 6 6

This shows that setConfig gets called more than once because both __init__ 
and setConfig are cooperative methods.

I have been thinking about this for a day now and I cannot find a good 
solution.  I imagine this would be a common problem and that there would be 
a recipe somewhere, but I couldn't find one (I looked in the Python 
Cookbook).  I've thought of creating 2 separate methods instead of 
setConfig, one that does the "local" configuration and another one that 
takes care of invoking super.  But I don't like the idea of creating 2 
methods in each class and I haven't been able to think of a way to solve the 
problem with just one change in the base class that would be inherited by 
all the subclasses.

Anyone has any ideas?  Thanks.

Dan 





More information about the Python-list mailing list