** 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'>
(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
** 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'>
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'>
For that matter, the type of type is type as well.
>>> type(type)
<class 'type'>
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'>
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)