InterviewSolution
| 1. |
What is a metaclass in Python? |
||||||
|
Answer» Any class in Python code, whether built-in or user defined, is an object of ‘type’ class which is called a 'metaclass'. A metaclass is a class whose objects are also classes. This relationship can be understood by the following diagram: Python library's built-in function type() returns class to which an object belongs. >>> num=50 >>> type(num) <class 'int'> >>> numbers=[11.,22,33] >>> type(numbers) <class 'list'> >>> lang='Python' >>> type(lang) <class 'str'>Same thing applies to object of a user defined class >>> class user: def __init__self(): self.name='xyz' self.age=21 >>> a=user() >>> type(a) <class '__main__.user'>Interestingly, class is also an object in Python. Each class, both built-in class and a user defined class is an object of type class >>> type(int) <class 'type'> >>> type(list) <class 'type'> >>> type(str) <class 'type'> >>> type(user) <class 'type'>Can be rephrased and mentioned at the START ALONG with the diagram and the tables above can be used as an example instead. The type class is the default metaclass. The type() function used above takes an object as ARGUMENT. The type() function's three argument variation is used to define a class dynamically. Its prototype is as follows: newclass=type(name, bases, dict)The function returns class that has been CREATED dynamically. Three arguments of type function are:
Following statement creates user dynamically using type() function: >>> user=type('user',(), {'name':'xyz', 'age':21})We can now use this class in the same manner as we do when it is defined using class statement: >>> a=user() >>> a.name,a.age ('xyz', 21) >>> type(a) <class '__main__.user'>Similarly you can add instance METHOD dynamically. Moreover, this class can be used to create an inherited class as well. >>> newuser=type('newuser',(user,),{}) >>> b=newuser() >>> b.userdata() name:xyz, age:21As mentioned above, type is the default metaclass. A class that it inherited from type is a custom metaclass. >>> class NewMetaClass(type): passUsing this custom metaclass to create new class as follows: >>> class newclass(metaclass=NewMetaClass): passNewly created class can even be used as base for other. >>> class subclass(newclass): passThe custom metaclass is a type of both the classes. >>> type(NewMetaClass) <class 'type'> >>> type(newclass) <class '__main__.NewMetaClass'> >>> type(subclass) <class '__main__.NewMetaClass'>Construction of subclass of user defined metaclass can be customized by overriding __new__ magic method. In following example, we declare a metaclass (NewMetaClass) having __new__() method. It returns instance of new class which in turn is initialized by __init__() method as usual in the derived class. lass NewMetaClass(type): def __new__(cls, name, bases, dict): print ('name:',name) print ('bases:',bases) print ('dict:',dict) inst = super().__new__(cls, name, bases, dict) return inst class myclass(metaclass=NewMetaClass): pass class newclass(myclass,metaclass=NewMetaClass): def __init__(self): self.name='xyz' self.age=21When we declare an object of newclass and print its attributes, following output is displayed. x=newclass() print('name:',x.name, 'age:',x.age) print ('type:',type(x))Output: name: myclass bases: () dict: {'__module__': '__main__', '__qualname__': 'myclass'} name: newclass bases: (<class '__main__.myclass'>,) dict: {'__module__': '__main__', '__qualname__': 'newclass', '__init__': <function newclass.__init__ at 0x7f65d8dfcf28>} name: xyz age: 21 type: <class '__main__.newclass'>We can thus customize the metaclass and creation of its subclasses. |
|||||||