I have a case where my class has a custom metaclass, which calls a class method of the class when creating it, something like:
class Metaclass(type):
def __new__(cls, name, bases, attrs):
...
new_class = super(Metaclass, cls).__new__(cls, name, bases, attrs)
...
new_class.get_fields() # do something
...
return new_class
class FooBar(object):
__metaclass__ = Metaclass
@classmethod
def get_fields(cls):
...
(Example of such code is in Tastypie.)
The problem is if I want to do:
class NewBar(FooBar):
@classmethod
def get_fields(cls):
super(NewBar, cls).get_fields()
...
This does not work because NewBar is not yet created at the point super is invoked (program flow is still in metaclass). So, is there any workaround?
I know that probably get_fields method could become a method of metaclass, but this would make inheritance much harder to implement (you would have to define both new metaclass and class itself, not nice to developers wanting to extend this classes).
(Python 2.7.)
If
NewBarcan be unavailable whenget_fieldsis invoked, you can still find it in the MRO ofcls:Although this code looks funny, it works correctly and is significantly simpler than the alternatives proposed in the question. While most calls to
superwith a non-constant first argument (such as unqualifiedsuper(cls, cls)) are incorrect and break inheritance, this one is safe because the generator expression is nothing but an unconventional way to get a hold ofNewBar.When looking for the clas in the MRO we check for both class and module name (available as
__name__, as pointed out by Mitar) to avoid a false positive ifothermodule.NewBarinherits fromthismodule.NewBar.