1

Suppose I have a base class as following:

class User:
    user_types = []
    def __init__(self, name, age):
        self.name = name
        self.age = age

And then I want to create a subclass, which will then be added to user_types

class Farmer(User):
    def harvest(self):
        print("%s just harvested his plantation!" %self.name)

Now I can achieve what I'm trying to do, by simply saying

User.user_types.append(Farmer)

But how could I achieve this if I wanted it to be automatic, and to be done for every subclass? Let's say there will be 400 subclasses, it would be a pain in the ass to manually do that for all of them.

0

2 Answers 2

4

New style classes have this functionality:

>>> User.__subclasses__()
[<class '__main__.Farmer'>]

Just need to make User inherit from object in case you're using Python 2.x.

If you need all the subclasses of each subclass, you can still avoid metaclasses with this:

def get_subclasses(c):
    subs = set(c.__subclasses__())
    return subs.union(*(get_subclasses(i) for i in subs))
Sign up to request clarification or add additional context in comments.

Comments

2

You can use a metaclass do solve your problem:

class Meta(type):
    def __new__(meta, classname, bases, classDict):
        new_class = type.__new__(meta,classname,bases,classDict)
        for base in bases:
            if hasattr(base,'register'):
                base.register(new_class)
        return new_class

class Base(object):
    __metaclass__ = Meta

    subclasses = []

    @classmethod
    def register(cls,derived):
        cls.subclasses.append(derived)


class A(Base):
    pass

class B(A):
    pass

class C(Base):
    pass

print Base.subclasses

The output is:

[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.