Issue
I have a class object, cls
. I want to know its metaclass. How do I do this?
(If I wanted to know its parent classes, I would do cls.__mro__
. Is there something like this to get the metaclass?)
Solution
Ok - so, a class's metaclass is just its own "type", and can be given by
type(cls)
and other means such as cls.__class__
.
In Python 3.x there are no further ambiguities - as the syntax for creating a metaclass just passes it as a named parameter on the class declaration statement anyway.
However, the syntax used for creating a metaclass in Python 2.x generates a side-effect that is worth noting.
Upon doing
class A(object):
__metaclass__ = MyMeta
The __metaclass__
attribute is set to that value in the actual class, even if the actual metaclass is another one.
Consider:
def class_pre_decorator(name, bases, namespace):
# do something with namespace
return type(name, bases, namespace)
This is a callable that can be used in the metaclass declaration of both Python 2 and 3 - and it is valid. After resolving, the actual metaclass in both cases will simply be type
. However, in Python 2.x, cls.__metaclass__
will point to the callable class_pre_decorator
, even tough type(cls)
returns type
, which is the correct metaclass.(Note that using callables in this way, they will not be used agian when the class is further subclassed)
There is no way in Python 3 to guess the callable actually used to instantiate a class if it gives no other hint (like setting an attribute on the class) that it was used:
# python 2
class A(object):
__metaclass__ = class_pre_decorator
On the console:
In [8]: type(A)
Out[8]: type
In [9]: A.__metaclass__
Out[9]: <unbound method A.class_pre_decorator>
and
# Python 3
class A(metaclass=class_pre_decorator):
pass
And trying to read A.__metaclass__
will simply raise an AttributeError.
Answered By - jsbueno
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.