Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine the metaclass of a class?

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?)

like image 763
Pro Q Avatar asked May 08 '17 17:05

Pro Q


People also ask

How will you set the metaclass of class A to class B?

In order to set metaclass of a class, we use the __metaclass__ attribute. Metaclasses are used at the time the class is defined, so setting it explicitly after the class definition has no effect.

What is a metaclass in programming?

In object-oriented programming, a metaclass is a class whose instances are classes. Just as an ordinary class defines the behavior of certain objects, a metaclass defines the behavior of certain classes and their instances. Not all object-oriented programming languages support metaclasses.

What is a metaclass in UML?

In UML, a metaclass is an instance of the Class element with the. stereotype Standard::Metaclass. The code you describe determines if a. class is a metaclass instead by checking whether the Metaclass. stereotype is applied.

What is a metaclass in C++?

You can define your own metaclasses that is a type of type that allows to define types. To make it clearer, a class describes what an object looks like, and is used at runtime to instantiate objects. A metaclass describes what a class looks like, and is used at compile time to instantiate classes.


1 Answers

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.

like image 156
jsbueno Avatar answered Sep 23 '22 13:09

jsbueno