hmm, lets call it: generic __init__ problem

Michele Simionato michele.simionato at
Wed Feb 18 18:08:32 CET 2004

paul kölle <koelle1 at> wrote in message news:<c0u0fa$1asj0f$1 at>...
> Hi list,
> in the course of writing a small app, I tried to design a class, which 
> would allow to derive its behaviour solely from its name, so that I 
> would be able to write one abstract class with the logic and get 
> different objects/instances by subclassing with appropriate names. 
> Consider the following:
> ATTRS = {'one':['attr1', 'attr2'],
> 	 'two':['attr3','attr4'],
> 	 'three':['attr5','attr6'],
> 	 'four':['attr7','attr8']}
> class one:
> 	def __init__(self, *args, **kwargs):
> 		## get allowed attributes...
> 		for attr in ATTRS[self.__class__.__name__]:
> 			self.__dict__[attr] = ''
> 		## unknown attributes are silently ignored...
> 		for item in kwargs.keys():
> 			if self.__dict__.has_key( item ):
> 				 self.__dict__[item] = kwargs[item]
> 			else:
> 				 pass
> 		## init all parents...
> 		parents = self.__class__.__bases__
> 		if parents:
> 			for i in range(len(parents)):
> 			apply(parents[i].__name__.__init__,\ 								(self,)+args, kwargs)

Uhm ... I am quite sure this could be done better, but it is not
completely clear what you are trying to do. The parents[i].__name__.__init__
is clearly bogus, and the loop over "i" makes me say "ickkk!".
Moreover, it is completely useless since even fixing it will generate
a recursion error (__init__ of one instance would call __init__ of
the *same* class). In principle, you would need "super", but in
this case you are probably better with "dir": dir automatically retrieves the
attributes from the parents. Here is an example:

    'one':  ['attr1', 'attr2'],
    'two':  ['attr3', 'attr4'],
    'three':['attr5', 'attr6'],
    'four': ['attr7', 'attr8']}

class one:
    def __init__(self, *args, **kwargs):
        for item in dir(self): 
            # a way to pass attributes from parents to self by hand
            if item.startswith("__"):
                pass # skip private and special names
                setattr(self,item,getattr(self,item)) #put in self.__dict__
        for attr in ATTRS[self.__class__.__name__]:
            self.__dict__[attr] = ''
        for item in kwargs.keys():
            if self.__dict__.has_key( item ):
                self.__dict__[item] = kwargs[item]
            else: #useless but may help readability
class two(one):
    def foo(self):

class three(one):
    def bar(self):

class four(two, three):
    def wiskey_bar(self):


print dir(i1)

print dir(i2)

print dir(i3)

print dir(i4)

This is probably not what you want: by I suggest you consider
changing the attributes of the class with setattr(self.__class__,name,value)
if you want inheritance to work. The issue is that the dictionary of one 
instance is local to the instance and it is not inherited, so you want to 
change the dictionary of the class.
Does this helps?

                      Michele Simionato

More information about the Python-list mailing list