ActiveState Code

Recipe 425119: autosetup for simplified default values


If each class's __init__ is used to set default values, it requires that one use super() or explicit parentclass.__init__() calls . Such ugly boilerplate can be avoided with this recipe.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Base(object):
   def __init__(self, *args, **kwds):
       self.autosetup(self.__class__, [], **kwds)

   def setup(self, **kwds):
       pass

   def autosetup(self, cls, called, **kwds):
       for base in cls.__bases__:
           try:
               b = base.setup
           except AttributeError:
               pass
           else:
               if b not in called:
                   called = self.autosetup(base, called, **kwds)

       cls.setup(self, **kwds)
       called.append(cls.setup)
       return called

# Sample Usage
class A(Base):
   def setup(self, foo, **kwds):
       print "A",foo

class B(Base):
   def setup(self, blah, **kwds):
       print "B", blah

class C(B):
   def setup(self, blech, **kwds):
       print "C", blech

class D(A, C):
   def setup(self, frog, **kwds):
       print "D", frog

class E(C):
   pass

class F(D, E):
   def setup(self, toad, foo, frog, **kwds):
       print "F", foo, frog, toad

x = F(foo=1, blah=2, blech=3, frog=4, toad=5)

Discussion

Using super() is ugly and painful, and for one of the most common cases - allowing classes to set default values - unnecessary.

It was originally created for game objects where a user class can inherit from a large number of mixins, eg: "Cake(Base, CanWriteOn, CanBurn, CanTake, CanEat)...", but should be of general use. The same technique could be used to do an autoverify() after the autosetup(), to check values set by the user that aren't otherwise checked.

There's some discussion on using super() at http://mail.python.org/pipermail/python-dev/2005-January/050656.html

Tim Delaney has an autosuper recipe at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195

Sign in to comment