Классы Python сами по себе являются объектами - как, например, - их метакласса.
Метакласс по умолчанию, который применяется, когда вы определяете классы как:
class foo:
...
метакласс используется для применения некоторого правила ко всему набору классов. Например, предположим, что вы создаете ORM для доступа к базе данных, и вы хотите, чтобы записи из каждой таблицы относились к классу, сопоставленному с этой таблицей (на основе полей, бизнес-правил и т. Д.,), Возможное использование метакласса например, логика пула соединений, которая является общей для всех классов записей из всех таблиц. Другое использование - логика для поддержки внешних ключей, которая включает в себя несколько классов записей.
когда вы определяете метакласс, вы подклассируете тип и можете переопределить следующие магические методы для вставки вашей логики.
class somemeta(type):
__new__(mcs, name, bases, clsdict):
"""
mcs: is the base metaclass, in this case type.
name: name of the new class, as provided by the user.
bases: tuple of base classes
clsdict: a dictionary containing all methods and attributes defined on class
you must return a class object by invoking the __new__ constructor on the base metaclass.
ie:
return type.__call__(mcs, name, bases, clsdict).
in the following case:
class foo(baseclass):
__metaclass__ = somemeta
an_attr = 12
def bar(self):
...
@classmethod
def foo(cls):
...
arguments would be : ( somemeta, "foo", (baseclass, baseofbase,..., object), {"an_attr":12, "bar": <function>, "foo": <bound class method>}
you can modify any of these values before passing on to type
"""
return type.__call__(mcs, name, bases, clsdict)
def __init__(self, name, bases, clsdict):
"""
called after type has been created. unlike in standard classes, __init__ method cannot modify the instance (cls) - and should be used for class validaton.
"""
pass
def __prepare__():
"""
returns a dict or something that can be used as a namespace.
the type will then attach methods and attributes from class definition to it.
call order :
somemeta.__new__ -> type.__new__ -> type.__init__ -> somemeta.__init__
"""
return dict()
def mymethod(cls):
""" works like a classmethod, but for class objects. Also, my method will not be visible to instances of cls.
"""
pass
во всяком случае, эти два являются наиболее часто используемыми крючками. метаклассирование является мощным, и выше не далеко и исчерпывающий список применений для метаклассирования.