5

Is it possible to leave a parent class unspecified until an instance is created?
e.g. something like this:

class SomeParentClass:
    # something

class Child(unspecifiedParentClass):
    # something

instance = Child(SomeParentClass)

This obviously does not work. But is it possible to do this somehow?

martineau
  • 119,623
  • 25
  • 170
  • 301
Thrasi
  • 418
  • 1
  • 5
  • 15
  • 1
    In the meanwhile, have a look at the accepted answer here: http://stackoverflow.com/questions/15247075/how-can-i-dynamically-create-derived-classes-from-a-base-class – tamasgal Sep 08 '13 at 11:27
  • Or if don't want / need to create classes on the fly you could ditch inheritance and just pass some "helper" instance to child's constructor. Python's duck typing will cope with most requirements – Tony Hopkinson Sep 08 '13 at 11:33
  • 2
    You can create a class at run-time using `type`, but creating a class and *afterwards* modifying its mro doesn't seem something you can do easily, at least not from the python side(and, anyway, it's a really huge code smell that there's something wrong in the design). – Bakuriu Sep 08 '13 at 11:50

3 Answers3

6

You can change the class of an instance in the class' __init__() method:

class Child(object):
    def __init__(self, baseclass):
        self.__class__ = type(self.__class__.__name__,
                              (baseclass, object),
                              dict(self.__class__.__dict__))
        super(self.__class__, self).__init__()
        print 'initializing Child instance'
        # continue with Child class' initialization...

class SomeParentClass(object):
    def __init__(self):
        print 'initializing SomeParentClass instance'
    def hello(self):
        print 'in SomeParentClass.hello()'

c = Child(SomeParentClass)
c.hello()

Output:

initializing SomeParentClass instance
initializing Child instance
in SomeParentClass.hello()
martineau
  • 119,623
  • 25
  • 170
  • 301
  • This is the better solution imo. – xiao Dec 05 '13 at 17:59
  • @linxtion Care to explain why? I actually think the accepted answer is far more transparent and flexible. – Slater Victoroff Nov 03 '16 at 14:56
  • I don't remember much about this since its been 3 years. Looking at it again, the accepted solution is easier to read, but its goes against pep8. Really its up to you. – xiao Nov 03 '16 at 16:11
2

Have you tried something like this?

class SomeParentClass(object):
    # ...
    pass

def Child(parent):
    class Child(parent):
        # ...
        pass

    return Child()

instance = Child(SomeParentClass)

In Python 2.x, also be sure to include object as the parent class's superclass, to use new-style classes.

Lethargy
  • 1,859
  • 14
  • 15
0

You can dynamically change base classes at runtime. Such as:

class SomeParentClass:
    # something

class Child():
    # something

def change_base_clase(base_class):
    return type('Child', (base_class, object), dict(Child.__dict__))()

instance = change_base_clase(SomeParentClass)

For example:

class Base_1:
    def hello(self):
        print('hello_1')

class Base_2:
    def hello(self):
        print('hello_2')

class Child:pass

def add_base(base):
    return type('Child', (base, object), dict(Child.__dict__))()

# if you want change the Child class, just:
def change_base(base):
    global Child
    Child = type('Child', (base, object), dict(Child.__dict__))

def main():
    c1 = add_base(Base_1)
    c2 = add_base(Base_2)
    c1.hello()
    c2.hello()

main()

Result:

hello_1
hello_2

Works well in both python 2 and 3.

For more information, see the related question How to dynamically change base class of instances at runtime?

Community
  • 1
  • 1
atupal
  • 16,404
  • 5
  • 31
  • 42