I want to automatically run a class method defined in a base class on any derived class during the creation of the class. For instance:
class Base(object):
@classmethod
def runme():
print "I am being run"
def __metclass__(cls,parents,attributes):
clsObj = type(cls,parents,attributes)
clsObj.runme()
return clsObj
class Derived(Base):
pass:
What happens here is that when Base is created, ”runme()” will fire. But nothing happens when Derived is created.
The question is: How can I make ”runme()” also fire when creating Derived.
This is what I have thought so far: If I explicitly set Derived‘s metaclass to Base‘s, it will work. But I don’t want that to happen. I basically want Derived to use the Base‘s metaclass without me having to explicitly set it so.
See this answer. Basically, when calling
type(cls,parents,attributes), you are creating a class without passing in the information about what that class’s metaclass is. Thus, the class that is returned doesn’t have the metaclass you want it to; instead it has metaclasstype. (Ironically, by defining__metaclass__to do as it does, you are explicitly causing your class to not have that metaclass.) Instead of directly calling type, you need to calltype.__new__(meta, cls, parents, attrs), where meta is the metaclass.However, you can’t achieve this when you define
__metaclass__inline. From inside your__metaclass__method, you have no way to refer to that method, because it’s a method of a class that hasn’t been defined yet. You want to do something like. . . but there’s nothing you can put in for
metaclassGoesHereto make it do the right thing, because what you’re trying to refer to is the method inside which you’re trying to refer to it.So just define your metaclass externally.