how to dynamically instantiate an object inheriting from several classes?

Matimus mccredie at
Mon Nov 24 19:10:22 CET 2008

On Nov 21, 2:11 pm, Joe Strout <j... at> wrote:
> I have a function that takes a reference to a class, and then  
> instantiates that class (and then does several other things with the  
> new instance).  This is easy enough:
>     item = cls(self, **itemArgs)
> where "cls" is the class reference, and itemArgs is obviously a set of  
> keyword arguments for its __init__ method.
> But now I want to generalize this to handle a set of mix-in classes.  
> Normally you use mixins by creating a class that derives from two or  
> more other classes, and then instantiate that custom class.  But in my  
> situation, I don't know ahead of time which mixins might be used and  
> in what combination.  So I'd like to take a list of class references,  
> and instantiate an object that derives from all of them, dynamically.
> Is this possible?  If so, how?
> Thanks,
> - Joe

I wrote this a while ago. I sort of regret it though. Mixins could
(and I will argue should) be avoided most of the time by delegating to
other objects with less functionality. Utilizing many mixin classes
tends to just make gigantic classes. This is a huge violation of the
"Single Responsibility Principle". That isn't to say that I don't
think there is a place for multiple inheritance. Multiple inheritance
to the point where it is easier to write a metaclass to automatically
generate your __init__ method than it is to write it yourself is a
good indicator that you have gone too far. Which is what I did.


import inspect

class AutoGenInitMetaError(Exception):
    """ Exception is raised if AutoGenInitMeta cannot auto-generate a
    constructor for a class because of conflicting parameters in base

class AutoGenInitMeta(type):
    """ Meta-Class for automatically generating __init__ method for a
    with multiple mixin base classes.
    def __new__(cls, name, bases, assoc):
        if "__init__" in assoc:
            return super(AutoGenInitMeta, cls).__new__(cls, name,
bases, assoc)
        args = ['self']
        dargs = []
        defaults = []
        tmpl = []
        varg = None
        vkwarg = None
        tmpl = ["def __init__%s:\n"]
        for base in bases[::-1]:
            a, va, vkw, d = argspec = inspect.getargspec
            argspecfmt = inspect.formatargspec(*argspec[:3])
            if d:
                num_d = len(d)
                args += a[1:-num_d]
                defaults += d
                dargs += a[-num_d:]
                # remember to stip off self
                args += a[1:]
            if va is not None:
                if varg is not None:
                    raise AutoGenInitMetaError(
                        "There must be only one `*` arg in base
                varg = va

            if vkw is not None:
                if vkwarg is not None:
                    raise AutoGenInitMetaError(
                        "There must be only one `**` arg in base
                vkwarg = vkw
            tmpl.append("    %s.__init__%s\n"%(base.__name__,
        tmpl = "".join(tmpl)
        argspec = (args + dargs, varg, vkwarg, defaults)
        exec tmpl%inspect.formatargspec(*argspec) in globals(), assoc

        return super(AutoGenInitMeta, cls).__new__(cls, name, bases,

How do you use it?

>>> class C(object):
...     def __init__(self, a, b):
...         self.a = a
...         self.b = b
>>> class D(object):
...     def __init__(self, c, d):
...         self.c = c
...         self.d = d
>>> class CD(C, D):
...     __metaclass__ = AutoGenInitMeta
>>> x = CD(1,2,3,4)
>>> x.a
>>> x.b
>>> x.c
>>> x.d

Notice that the arguments to D came before C. So you have to list the
classes in reverse order of how you want the arguments listed.

I post it as an example of a "neat python trick". Even the "neat"
might be self indulgence. I encourage anybody tempted to use this to
refactor/redesign instead.


More information about the Python-list mailing list