TL;DR: This "empty __class__ cell"
error will happen when the metaclass tries to call a method in the defined class (or instantiate it) before it is done with its __new__
and __init__
,and the called method uses super
. The error will also happen if one writes a call to super()
in a function defined outside of a class body, and tries to add this method to an existing class and use it. (update: this behavior has been fixed in Python 3.6)
Python 3 super makes an implicit reference to a "magic" __class__
[*] name which behaves as a cell variable in the namespace of each class method.
This variable is created automatically at the end of the class creation mechanism - i.e. whenever there is a class body in Python, the metaclass's __new__
and __init__
are run - when __init__
finishes, the __class__
cell is populated and made available to the class's methods.
What is going on here, is that likely (I have not looked at all the code) in the PluginMeta
initialization code, the class's __init__
is called, before the end of the metaclass __init__
- since one of the points of this metaclass is handling singletons - what is likely to happen is that the metaclass mechanism is instantiating the single-instance and populating __instance__
before returning from the metaclass' __init__
. The implicit __class__
used by super does not exist at this point.
Thus, referencing the superclass by the hardcoded name, as one had to do prior to super
in Python2 will work - and is the best way to achieve what you want there.
*
- This is not the self.__class__
attribute of the instance, it is a __class__
variable actually available inside methods:
class A:
def a(self):
print ("Instance's class: {}, "
"actual class where this line is coded: {}".format(
self.__class__, __class__))
class B(A):
pass
And running this we have:
>>> B().a()
Instance's class: <class '__main__.B'>, actual class where this line is coded: <class '__main__.A'>
>>>
From the Python datamodel:
__class__
is an implicit closure reference created by the compiler if
any methods in a class body refer to either __class__
or super
. This
allows the zero argument form of super()
to correctly identify the
class being defined based on lexical scoping, while the class or
instance that was used to make the current call is identified based on
the first argument passed to the method.
For more details, please check PEP 3135
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…