DEV Community

Clouditate
Clouditate

Posted on • Originally published at clouditate.com

Python meta classes

What is a python metaclass

Metaclasses in python are a useful way to describe the behavior of a class. Metaprogramming is a programming technique used in a computer software component to have the ability to treat other components as described in their data. It means that a program can be designed to understand and even change other programs or modify it's specification while executing. Python has a perfect syntax structure and modules that support meta class definition. Many people are better off not using metaclasses in python, but if you're using the Django web framework, metaclasses are used in model and form definition. Read more on Django metaclasses.

A meta class in python can simply be defined as a class of class that describes the behavior of the class. A class is the instance of a meta class

Lisp programming language has a reputation for having a good meta programming facility and easy syntax. I advice you check basic Lisp meta programming.

Python has old style and new style class definition syntax. Let's explore of those class varieties:

Old style python class definition

Classes are not defined by inheriting from a base class. An instance of an old-style class is implemented from an instance. In old classes, obj.__class__ represent the class and type(obj) return the instance of the class. Here is an example:

#
#
# Old style class definition

class Hello:
   pass

obj = Hello()
obj.__class__

type(obj)

#
#
#

The old style python class definition was removed in python 3 >. Let's look at the new style of defining classes.

New style python class definition

A class is created by inheriting from Object class. It is the only way to define a class since python 3. In the new style definition obj.__class__ is the same as type(obj). That's the main difference between the two python class definition. Example code:

#
#
# New class definition example

class MyClass(Object):
   pass

obj = MyClass()
print(type(obj) is obj.__class__)

# end example
#
#

The above code will return true because obj.__class__ is same as type(obj).

Python classes and types

Everything in python is an object. So are classes. Let's look at the type of class. The type of an object is a class, but the type of class is type.

Type is the metaclass and classes are the instances of the metaclass. This means that any python 3 class is an instance of the meta class.

Creating custom python metaclass

Python allows a programmer to customize the class creation by passing the metaclass keyword in the class definition syntax. You can also do so by inheriting a class in which a metaclass was defined. Here is an example.

#
#
# Define Meta Class
class MyMetaClass(type):
    pass

# Define a class that takes the MyMetaClass 
class MyClass(metaclass=MyMetaClass):
    pass

# A class thatinherits a MyClass class
class MyChildclass(MyClass):
    pass

#
#
#

If you define a class and decide not to define a custom meta class, the default type is used.

__new__ and __init__ , python meta classes

You can define python metaclasses using __new__ and __init__ keywords. Let's look at the example implimentation.

#
#
#

class MetaClass(type):
    def __new__(cls, name, bases, dict):
        pass

class AnotherMetaClass(type):
    def __init__(self, name, bases, dict):
        pass

#
#
#

__new__ is used if you want to define a dictionary (dict) or tuples before you create the class. __new__ is called after the object has been created to initialize it.

Singleton Class using a Metaclass

Singleton class is a class that can be instantiated by only one object. In python you can implement a singleton design using metaclasses. Example code.

#
#
#
class SingletonMetaClass(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(SingletonMeta,cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class MyClass(metaclass=SingletonMeta):
    pass
#
#
#

Top comments (0)