This question already has an answer here:
- What are metaclasses in Python? 15 answers
I have some confusion regarding meta-classes.
With inheritance
class AttributeInitType(object):
def __init__(self,**kwargs):
for name, value in kwargs.items():
setattr(self, name, value)
class Car(AttributeInitType):
def __init__(self,**kwargs):
super(Car, self).__init__(**kwargs)
@property
def description(self):
return "%s %s %s %s" % (self.color, self.year, self.make, self.model)
c = Car(make='Toyota', model='Prius', year=2005, color='green')
print c.description
With meta class
class AttributeInitType(type):
def __call__(self, *args, **kwargs):
obj = type.__call__(self, *args)
for name, value in kwargs.items():
setattr(obj, name, value)
return obj
class Car(object):
__metaclass__ = AttributeInitType
@property
def description(self):
return "%s %s %s %s" % (self.color, self.year, self.make, self.model)
c = Car(make='Toyota', model='Prius', year=2005,color='blue')
print c.description
As above example is not useful as practically but just for understanding,
I have some questions Like,
What is use of metaclass and when do I use it?
What is the difference/similarity between a meta class and inheritance?
Where should one use a meta class or inheritance?
1) What is use of metaclass and when to use it?
Metaclasses are to classes as classes are to objects. They are classes for classes (hence the expression "meta").
Metaclasses are typically for when you want to work outside of the normal constraints of OOP.
2) What is difference/similarity between metaclass and inheritance?
A metaclass is not part of an object's class hierarchy whereas base classes are. So when an object does
obj.some_method()
it will not search the metaclass for this method however the metaclass may have created it during the class' or object's creation.In this example below, the metaclass
MetaCar
gives objects adefect
attribute based on a random number. Thedefect
attribute is not defined in any of the objects' base classes or the class itself. This, however, could have been achieved using classes only.However (unlike classes), this metaclass also re-routes object creation; in the
some_cars
list, all the Toyotas are created using theCar
class. The metaclass detects thatCar.__init__
contains amake
argument that matches a pre-existing class by that name and so returns a object of that class instead.Additionally, you'll also note that in the
some_cars
list,Car.__init__
is called withmake="GM"
. AGM
class has not been defined at this point in the program's evaluation. The metaclass detects that a class doesn't exist by that name in the make argument, so it creates one and updates the global namespace (so it doesn't need to use the return mechanism). It then creates the object using the newly defined class and returns it.3) Where should one use metaclass or inheritance?
As mentioned in this answer and in the comments, almost always use inheritance when doing OOP. Metaclasses are for working outside those constraints (refer to example) and is almost always not necessary however some very advanced and extremely dynamic program flow can be achieved with them. This is both their strength and their danger.