1

I have 5 classes that are all subclasses of a parent class. I want to define new subclasses for each of these classes by adding an identical method to each of them. Is there a way to do this dynamically? Does this have a name in OOP terminology?

In below new_method is exactly the same for all cases so I'd prefer to repeat myself.

class A(MySuperClass)
class B(MySuperClass)
class C(MySuperClass)
class D(MySuperClass)

class AAA(A):

    def new_method():
        ...

class BBB(B):

    def new_method():
        ...

class CCC(C):

    def new_method():
        ...

class DDD(D):

    def new_method():
        ...
Bernardo Duarte
  • 4,074
  • 4
  • 19
  • 34
Milad
  • 4,901
  • 5
  • 32
  • 43

3 Answers3

4

You can solve repetition by creating new class that contains your new_method as follows:

class A(MySuperClass)
class B(MySuperClass)
class C(MySuperClass)
class D(MySuperClass)

class Mixin():
    def new_method():
        pass

class AAA(A, Mixin):
    pass

This is called multi-inheritance. you can consider here inheritance as both specialization mechanism and also code sharing.

adnanmuttaleb
  • 3,388
  • 1
  • 29
  • 46
2

Besides multiple inheritance, you can also use a decorator if it is more convenient to your code:

def add_new_method(cls):
    def new_method(self, ...):
        pass
    cls.new_method = new_method
    return cls

@add_new_method
class AAA(A):
    ...

However, if you don't necessarily need a new AAA subclass, but just wanted to add new_method to A, B, C, D from the superclass, then it's as easy as:

def new_method(self, ...):
    pass

A.new_method = new_method

Even better yet. If MySuperClass can be changed, you can simply do:

MySuperClass.new_method = new_method

# A, B, C and D will all have new_method automatically.
r.ook
  • 13,466
  • 2
  • 22
  • 39
  • This is interesting. I'm still wrapping my head around decorators. Am I right in thinking that when you decorate a class, the decorating happens immediately rather than when an instance of the class is created? And in your example the decorator receives the actual class rather than an instance of the class right? – Milad Feb 04 '19 at 19:02
  • Yes, they are immediately decorated after the definition. See this relevant question I just answered earlier today: https://stackoverflow.com/questions/54517806/when-does-class-level-decorator-decorates/54519391#54519391. And yes, decoration happens on the class, not the instance. – r.ook Feb 04 '19 at 19:13
0

You can use type to dynamically create classes:

class Foo(object):
    def __init__(self):
        print("NOTHING")

def func(self):
    print("ARRRGH")

Bar = type('Bar', (Foo,), {"func": func})
Bar2 = type('Bar2', (Foo,), {"func": func})
Bar3 = ... # Put in loop if you like.

b = Bar() # This will print "NOTHING", Bar2, Bar3 works the same way.
b.func() # will print "ARRRGH"
Rocky Li
  • 5,641
  • 2
  • 17
  • 33