Timmy
Timmy

Reputation: 12848

Adding inheritance to a class programmatically in python?

Can I make a class inherit a class "in-program" in Python?

heres what i have so far:

base = list(cls.__bases__)
base.insert(0, ClassToAdd )
base = tuple( base )
cls = type( cls.__name__, base, dict(cls.__dict__) )

Upvotes: 6

Views: 3554

Answers (4)

unutbu
unutbu

Reputation: 880657

Here is an example, using Greg Hewgill's suggestion:

class Foo(object):
    def beep(self):
        print('Hi')

class Bar(object):
    x = 1  

bar = Bar()
bar.beep()
# AttributeError: 'Bar' object has no attribute 'beep'

Bar = type('Bar', (Foo,object), Bar.__dict__.copy())
bar.__class__ = Bar
bar.beep()
# 'Hi'

Upvotes: 9

Jura Brazdil
Jura Brazdil

Reputation: 1100

Here's my solution that does take into account base classes of both the parent and the child classes.

import inspect    

def inherit_from(Child, Parent):

    # Prepare bases
    child_bases = inspect.getmro(Child)
    parent_bases = inspect.getmro(Parent)
    bases = tuple([item for item in parent_bases if item not in child_bases]) + child_bases

    # Construct the new return type
    Child = type(Child.__name__, bases, Child.__dict__.copy())

    return Child

Upvotes: 1

brent.payne
brent.payne

Reputation: 5527

Another option is not to change the class hierarchy dynamically but to decorate instances of objects with the new functionality. This is generally cleaner and easier to debug, because you only change objects that your code is in controls without having to make a cross cutting change to the whole class hierarchy.

def extend_object(obj):
    class ExtensionClass(obj.__class__):
        def new_functionality(self):
             print "here"
    obj.__class__ = ExtensionClass

b = Foo()
extend_object(b)
b.new_functionality()
#prints "here"

Upvotes: 2

Greg Hewgill
Greg Hewgill

Reputation: 994371

Yes, the type() built-in function has a three argument form that can do this:

type(name, bases, dict)

Return a new type object. This is essentially a dynamic form of the class statement. The name string is the class name and becomes the __name__ attribute; the bases tuple itemizes the base classes and becomes the __bases__ attribute; and the dict dictionary is the namespace containing definitions for class body and becomes the __dict__ attribute.

Upvotes: 5

Related Questions