DEV Community

221911001007
221911001007

Posted on

Meta-Classes In Python

** Meta-classes :

The term metaprogramming refers to the potential for a program to have knowledge of or manipulate itself. Python supports a form of metaprogramming for classes called meta-classes. Meta-classes are an esoteric OOP concept, lurking behind virtually all Python code.

** Old-Style Vs New-Style Classes :

In the Python, a class can be one of two varieties.

(1) Old-Style Classes :-

With old-style classes, class and type are not quite the same thing. An instance of an old-style class is always implemented from a single built-in type called instance. If obj is an instance of an old-style class, obj.class designates the class, but type(obj) is always instance.

>>> class Foo:
...     pass
...
>>> x = Foo()
>>> x.class
<class main.Foo at 0x000000000535CC48>
>>> type(x)
<type 'instance'>
Enter fullscreen mode Exit fullscreen mode

(2) New-Style Classes :-

New-style classes unify the concepts of class and type. If obj is an instance of a new-style class, type(obj) is the same as obj.class

  >>> class Foo:
  ...     pass
  >>> obj = Foo()
  >>> obj.__class__
  <class '__main__.Foo'>
  >>> type(obj)
  <class '__main__.Foo'>
  >>> obj.__class__ is type(obj)
   True
Enter fullscreen mode Exit fullscreen mode

** Type And Class :

In Python, everything is an object. Classes are objects as well. As a result, a class must have a type. What is the type of a class?
Consider the following

 >>> class Foo:
 ...     pass
 ...
 >>> x = Foo()

 >>> type(x)
 <class 'main.Foo'>

 >>> type(Foo)
 <class 'type'> 
Enter fullscreen mode Exit fullscreen mode

The type of x is class Foo. But the type of Foo, the class itself, is type. In general, the type of any new-style class is type. The type of the built-in classes you are familiar with is also type.

 >>> for t in int, float, dict, list, tuple:
 ...     print(type(t))
 ...
 <class 'type'>
 <class 'type'>
 <class 'type'>
 <class 'type'>
 <class 'type'>
Enter fullscreen mode Exit fullscreen mode

For that matter, the type of type is type as well.

 >>> type(type)
 <class 'type'>
Enter fullscreen mode Exit fullscreen mode

Type is a meta-class, of which classes are instances. Just as an ordinary object is an instance of a class, any new-style class in Python, and thus any class in Python 3, is an instance of the type meta-class.

In the above case:

(a) x is an instance of class Foo.
(b) Foo is an instance of the type meta-class.
(c) type is also an instance of the type meta-class, so it is an
instance of itself.

** Defining A Class Dynamically :

The built-in type() function, when passed one argument, returns the type of an object. For new-style classes, that is generally the same as the object’s class attribute:

 >>> type(3)
 <class 'int'>

 >>> type(['foo', 'bar', 'baz'])
 <class 'list'>

 >>> t = (1, 2, 3, 4, 5)
 >>> type(t)
 <class 'tuple'>

 >>> class Foo:
 ...     pass
 ...
 >>> type(Foo())
 <class '__main__.Foo'>
Enter fullscreen mode Exit fullscreen mode

You can also call type() with three arguments—type(< name >, < bases >, < dct >):

(1) specifies the class name. This becomes the name
attribute of the class.

(2) specifies a tuple of the base classes from which the
class inherits. This becomes the bases attribute of the
class.

(3) specifies a namespace dictionary containing
definitions for the class body. This becomes the dict
attribute of the class.

Calling type() in this manner creates a new instance of the type meta-class. In other words, it dynamically creates a new class.

** Is This Really Necessary :

It is the essence of how meta-classes work. They allow customization of class instantiation.

Top comments (0)