Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic metaclass to keep track of subclasses?

I'm trying to write a generic metaclass to track subclasses

Since I want this to be generic, I didn't want to hardcode any class name within this metaclass, therefore I came up with a function that generates the proper metaclass, something like:

def make_subtracker(root):
    class SubclassTracker(type):
        def __init__(cls, name, bases, dct):
            print('registering %s' % (name,))
            root._registry.append(cls)
            super(SubclassTracker, cls).__init__(name, bases, dct)
    return SubclassTracker

This way I could invoke it to generate a metaclass for a specific root class with:

__metaclass__ = make_subtracker(Root)

Here is where I bump into a problem. I cannot do this:

class Root(object):
   _registry = []
   __metaclass__ = make_subtracker(Root)

...because Root is not defined yet when I use make_subtracker(Root). I tried adding the __metaclass__ attribute later, so that at least it can be applied in subclasses:

class Root(object):
   _registry = []

Root.__metaclass__ = make_subtracker(Root)

...but this doesn't work. __metaclass__ has a special processing when the class definition is read, as defined in Customizing class creation.

I'm looking for suggestions in order to do this (either change a class' metaclass at runtime in a way that it is applied to its subclasses, or any other alternative).

like image 947
Carles Barrobés Avatar asked Oct 12 '10 13:10

Carles Barrobés


People also ask

Is type a metaclass Python?

type is a metaclass, of which classes are instances. Just as an ordinary object is an instance of a class, any new-style class in Python, and thus any class in Python 3, is an instance of the type metaclass.

Is metaclass inherited?

Every object and class in Python is either an instance of a class or an instance of a metaclass. Every class inherits from the built-in basic base class object , and every class is an instance of the metaclass type .

Is object a metaclass?

A class is an object, hence it is an instance of a metaclass. Like Smalltalk, in Objective-C, class methods are simply methods called on the class object, hence a class's class methods must be defined as instance methods in its metaclass.


1 Answers

Python does this automatically for new-style classes, as mentioned in this answer to the similar queston How to find all the subclasses of a class given its name? here.

like image 172
martineau Avatar answered Oct 13 '22 18:10

martineau