Rob Lao
Rob Lao

Reputation: 1613

Python, how to flexibly create subclass?

The detail question is I have a plenty of classes, say A, B, C, D...Z, they're all derived from 'Base'. They all have a method set_value. Now I need to have some subclasses to override set_value of A...Z, the implement of new set_value are the same for all. Theoretically, I can do something like class AA(A), class BB(B)... but it's tedious and not compact, I am not sure if one or all of A...Z need a subclass, I only want to create it when I create an object of the subclass.

In C++, I can do this easily via template:

template<class T>
class CCustom : public T
{
};
CCustom<vector<int> > obj1;
CCustom<list<char> > obj2;

Add some demo Python scripts here to help explain my question:

class Base:
def set_value(self):
    pass

class A(Base):
    def set_value(self):
        print('A.set_value')

class B(Base):
    def set_value(self):
        print('B.set_value')

class C(Base):
    def set_value(self):
        print('C.set_value')


def more_set_value():
    print('all subclasses do this')

class AA(A):
    def set_value(self):
        more_set_value()
        super().set_value()

class BB(B):
    def set_value(self):
        more_set_value()
        super().set_value()

class CC(C):
    def set_value(self):
        more_set_value()
        super().set_value()

a = AA()
b = BB()
c = CC()

a.set_value()
b.set_value()
c.set_value()

You can see AA, BB and CC are almost same. It's boring when there are hundreds this kind of class need to put in my project. I reckon there must be a way to write a factory function, to create AA, BB and CC dynamically, so that I can do following:

  AA = create_custom_subclass(A)
  a = AA()
  a.set_value()

Upvotes: 0

Views: 115

Answers (2)

freakish
freakish

Reputation: 56467

Classes are first-class citizens in Python, i.e. you can treat them like any other object. For example you can do a simple factory:

def create_custom_subclass(cls):
    class sub(cls):
        def set_value(self):
            more_set_value()
            super().set_value()
    return sub

AA = create_custom_subclass(A)
a = AA()
a.set_value()

Or you can do a mixin (uses less memory then a factory):

class Mixin:
    def set_value(self):
        more_set_value()
        super().set_value()

class AA(Mixin, A):
    pass

Upvotes: 1

Henrik
Henrik

Reputation: 4314

It's not entirely clear to me what it is you want to do, but I'll try to give you some pointers so to speak.

Unlinke C++, Python uses a dynamic type system, i.e. a variable can be assigned an object of any type. This gives you a whole range of possibilities.

class CustomClass(object):
    def __init__(self, obj_of_t_class):
        self.obj_of_t_class = obj_of_t_class

    def set_value(self, value):
        self.obj_of_t_class.some_method(value)
        # do something else here

As long as obj_of_t_class has the methods you try to call, Python doesn't care if it's of type A, B or Z.

This should be roughly equivalent to what you want to do with the C++ template class.

Upvotes: 0

Related Questions