Класс позволяет создать экземпляры класса, метакласс позволяет контролировать создание класса и его экземпляры.
Метакласс может являтся фабрикой классов.
Примеры для Python 2.7
class A(object):
pass
B = type('B',(object,),{})
C = type.__new__(type, 'C', (object,), {} )
class Meta(type):
pass
D = type.__new__( Meta , 'D', (object,), {} )
class A(object):
pass
B = type('B',(object,),{})
C = type.__new__(type, 'C', (object,), {} )
class Meta(type):
pass
D = type.__new__( Meta , 'D', (object,), {} )
print A, type(A)
print B, type(B)
print C, type(C)
print D, type(D)
<class '__main__.A'> <type 'type'>
<class '__main__.B'> <type 'type'>
<class '__main__.C'> <type 'type'>
<class '__main__.D'> <class '__main__.Meta'>
a = A()
a = type.__call__(A)
class Meta(type):
def __new__(cls, name, base, dic):
print 'new: %r = %r = %r' % (cls, name, base)
return type.__new__(cls,name,base,dic)
def __init__(cls, *args, **kwargs):
print 'init:', cls
def __call__(cls):
print 'call:', cls
return type(cls)
print 'Make class'
class Base():
__metaclass__ = Meta
class Foo(Base):
pass
print 'Make instance'
b = Base()
f = Foo()
Make class
new: <class '__main__.Meta'> = 'Base' = ()
init: <class '__main__.Base'>
new: <class '__main__.Meta'> = 'Foo' = (<class '__main__.Base'>,)
init: <class '__main__.Foo'>
Make instance
call: <class '__main__.Base'>
call: <class '__main__.Foo'>
class Car():
def name(self):
print 'Car'
class Bus():
def name(self):
print 'Bus'
class Meta(type):
def __new__(cls, name, base, dic):
if (len(base) == 2) and (type(base[1]) == str):
base = ( base[0], globals()[base[1]] )
dic['color'] = 'red'
return type.__new__(cls,name,base,dic)
class Base():
__metaclass__ = Meta
class Machine(Base,'Bus'):
speed = 100
m = Machine()
m.name()
print m.speed
print m.color
Bus
100
red
class Meta(type):
def __call__(cls, arg):
t = type(arg) # Определяем тип параметра
t2 = type('t2',(cls,t), {}) # Создаем класс на основе обрабатываемого класса и типа входящего параметра
i = t.__new__(t2, arg) # Создаем экземпляр типа входного параметра ( + инициализация типов int, str...)
t.__init__(i, arg) # Инициализация
return i
class Base():
__metaclass__ = Meta
class Combine(Base):
def name(self):
print 'Combine\n'
a = Combine(10)
print a
a.name()
b = Combine([1,2,3])
print b
b.name()
c = Combine({ 'id':'hello' })
print c
c.name()
10
Combine
[1, 2, 3]
Combine
{'id': 'hello'}
Combine