First note:
for this sort of code, it is easier to be using Python 3. More about this on the first solution and at the end of the answer.
So, the name of the class itself Foo
won't, obviously, be available inside the body of class Foo
: this name is only bound after the class instantiation is completely performed.
In Python 3, there is the parameterless version of super()
call, which can direct one to the superclass with no need for a explicit reference to the class itself. It is one of the few exceptions the language make to its very predictable mechanisms. It binds data to the super
call at compile time. However, even in Python 3 it is not possible to call a method that makes use of super
while the class is still being istantiated - i.e. before returning from the metaclass __new__
and __init__
methods. The data needed by the parameterless super
is silently bound after that.
However, in Python 3.6+ there is a mechanism that even precludes a metaclass: a class method named __init_subclass__
will be called on the superclasses after a class is created, and it could make normal use of (parameterless) super. This would work with Python 3.6:
class Base:
_instances = {}
def __init_subclass__(cls):
__class__._instances[cls.__name__] = cls()
...
class Foo(Base):
def __init__(self):
super().__init__()
Here, __class__
(not obj.__class__
) is another magic name, available along with parameterless super
, that always reference the class within which body it is used, never a subclass.
Now, a couple considerations on other methods: no code within the metaclass itself could work to instantiate a class, and the class methods needing to have a reference to the class in its name do not help. A class decorator would also not work, because the name is only bound after the return from the decorator. If you are coding your system within a framework which have an event loop, you could, on the metaclass __init__
schedule an event to create a class instance - that would work, but you need to be coding within such a context (gobject, Qt, django, sqlalchemy, zope/pyramid, Python asyncIO/tulip are examples of frameworks which have an event system that could make the needed callbacks)
Now, if you really need this in Python 2, I think the easiest way is to create a function to be called at the footer of each of your modules that would "register" the recently created classes.
Something along:
class MetaTest(type):
_instances = {}
def register():
import sys
module_namespace = sys._getframe(1).f_globals
for name, obj in f_globals.items():
if isinstance(obj, MetaTest):
MetaTest._instances[obj.__name__] = obj()
again: a a call to this "register" function should come at the last line of each of your modules.
The "meta" thing in here is introspecting the frame of the caller function itself to get its global variables automatically. You can get rid with it by making globals()
a required explicit parameter to the register function, and keeping the code easier to understand by third-parties.
Why Python 3
As of today, Python 2 is 2 years from End of Line. And a lot of improvements have been happening in the language in the last 8 years, including features in the class and metaclass models. I've seem a lot of people seems to stick with python 2 because as "python" is linked to Python 2 in their Linux installs, they think that is the default. Not true: it is just there for backwards compatibility - more and more Linux install use python3 as the default Python, usually installed alongside Python 2. And for your projects, it is nicer to use an isolated environment created with virtuaelnv anyway.