user30987
user30987

Reputation: 41

Get all subclasses of a base class as the base class's class attribute

Given a class inheriting from an abstract class, I'd like to be able to get all of its subclasses, but from within the class itself.

I've managed to create a @classmethod doing just that:

>>> Eukaryota.get_subtypes()
[<class '__main__.Plantae'>, <class '__main__.Fungi'>]

but is there a way I could do that using @property or through class attribute?

>>> Eukaryota.subtypes
[<class '__main__.Plantae'>, <class '__main__.Fungi'>]

(It seems that properties are only for intances of a class, not the class itself.)

Here is the one with @classmethod (using taxonomy):

from abc import ABCMeta, abstractmethod


class Kingdom(object):
    __metaclass__ = ABCMeta

    @classmethod
    @abstractmethod
    def get_subtypes(cls):
        pass


class Prokaryota(Kingdom):
    @classmethod
    def get_subtypes(cls):
        return cls.__subclasses__()


class Eukaryota(Kingdom):
    @classmethod
    def get_subtypes(cls):
        return cls.__subclasses__()

class Bacteria(Prokaryota):
    pass


class Plantae(Eukaryota):
    pass


class Fungi(Eukaryota):
    pass

Upvotes: 2

Views: 116

Answers (1)

blhsing
blhsing

Reputation: 106523

You can use a descriptor class:

class get_subclasses:
    def __get__(self, obj, objtype):
        return objtype.__subclasses__()

class Eukaryota(Kingdom):
    subtypes = get_subclasses()

so that Eukaryota.subtypes would return:

[<class '__main__.Plantae'>, <class '__main__.Fungi'>]

Upvotes: 1

Related Questions