How to create a Class and it's Object? The class definition starts with the class keyword. This is followed by a class name and is terminated with a colon. Example class Employee: salary = 10000 name = "John Doe" emp1 = Employee ( ) print ( emp1. salary ) print ( emp1. name ) Output 10000 John Doe

How to create an empty Class? The pass keyword used on the second line indicates an empty class without data attributes and methods. Example class Employee: pass e1 = Employee ( ) print ( e1 ) e1. name = "John Doe" print ( e1. name ) Output John Doe

How to create a Class using type Keyword? The type keyword used to create a new class on the fly and then instantiate it. Example e1 = type ( 'Employee' , ( ) , { } ) ( ) print ( e1 ) e1. name = "John Doe" print ( e1. name ) Output John Doe

How to create and call Method of a Class? Methods in classes are functions that belong to the class. Example class Employee: salary = 10000 name = "John Doe" def tax ( self ) : print ( self . salary * 0.10 ) emp1 = Employee ( ) print ( emp1. salary ) print ( emp1. name ) emp1. tax ( ) Output 10000 John Doe 1000.0

How to use the __init__() method to assign values to data attributes? Python classes have a special method named __init__ which is automatically executed when an instance of the class is created in memory. Example class Employee: def __init__ ( self , salary , name ) : self . salary = salary self . name = name emp1 = Employee ( 10000 , "John Doe" ) print ( emp1. salary ) print ( emp1. name ) Output 10000 John Doe

How to update Object properties? Example class Employee: def __init__ ( self , salary , name ) : self . salary = salary self . name = name emp1 = Employee ( 10000 , "John Doe" ) print ( emp1. salary ) emp1. salary = 20000 print ( emp1. salary ) Output 10000 20000

How to Delete object properties and object? You can delete objects and properties of object by using the del keyword.

Example class Employee: def __init__ ( self , salary , name ) : self . salary = salary self . name = name emp1 = Employee ( 10000 , "John Doe" ) del emp1. salary # Delete object property del emp1 # Delete object

How to check and compare type of an object? Class, or type, is an object that holds information about how to construct a certain kind of objects and what that kind of objects can do. A type is the class of a class. Like everything else in Python, classes themselves are objects, and you can pass them around, assign them to variables, etc. If you ask a class what its class is, you will get the answer type. If you ask a class instance what its class is, you will of course get the class. Example class Test ( object ) : pass print ( type ( Test ) ) obj1 = Test ( ) print ( type ( obj1 ) ) obj2 = Test ( ) print ( type ( obj1 ) is type ( obj2 ) ) Output < class 'type' > < class '__main__.Test' > True

How to copy all properties of an object to another object? Example class MyClass ( object ) : def __init__ ( self ) : super ( MyClass , self ) . __init__ ( ) self . foo = 1 self . bar = 2 obj1 = MyClass ( ) obj2 = MyClass ( ) obj1. foo = 25 obj2. __dict__ . update ( obj1. __dict__ ) print ( obj1. foo ) print ( obj2. foo ) Output 25 25

How to Iterate over object attributes? Calling dir on the object gives you back all the attributes of that object, including python special attributes.You can always filter out the special methods by using a list comprehension. Example class A ( ) : m = 1 n = 2 def __int__ ( self , x = 1 , y = 2 , z = 3 ) : self . x = x self ._y = y self .__z__ = z def xyz ( self ) : print ( x , y , z ) obj = A ( ) print ( dir ( obj ) ) print ( [ a for a in dir ( obj ) if not a. startswith ( '__' ) ] ) Output ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__int__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'm', 'n', 'xyz'] ['m', 'n', 'xyz']

Print all properties of an Object Example class Animal ( object ) : def __init__ ( self ) : self . eyes = 2 self . name = 'Dog' self . color = 'Spotted' self . legs = 4 self . age = 10 self . kids = 0 animal = Animal ( ) animal. tail = 1 temp = vars ( animal ) for item in temp: print ( item , ':' , temp [ item ] ) Output kids : 0 eyes : 2 name : Dog color : Spotted tail : 1 legs : 4 age : 10

How to create Data Attributes of a class dynamically? The setattr used to sets the named attribute on the given object with a specified value. Example class Employee: pass emp1 = Employee ( ) setattr ( emp1 , 'Salary' , 12000 ) emp2 = Employee ( ) setattr ( emp2 , 'Age' , 25 ) print ( emp1. Salary ) print ( emp2. Age ) Output 12000 25

How to create and use custom Self parameter? self is an object reference to the object itself, it does not have to be named self , but it has to be the first parameter of any function in the class. Example class Employee: def __init__ ( person , salary , name ) : person. salary = salary person. name = name def print_details ( emp ) : print ( str ( emp. salary ) + ' : ' + emp. name ) emp1 = Employee ( 10000 , 'John Doe' ) emp1. print_details ( ) Output 10000 : John Doe

How to use self parameter to maintain state of an object? When objects are instantiated, the object itself is passed into the self parameter. The Object is passed into the self parameter so that the object can keep hold of its own data.

Example class State ( object ) : def __init__ ( self ) : self . field = 5.0 def add ( self , x ) : self . field + = x def mul ( self , x ) : self . field * = x def div ( self , x ) : self . field / = x def sub ( self , x ) : self . field - = x s = State ( ) print ( s. field ) s. add ( 2 ) # Self is implicitly passed. print ( s. field ) s. mul ( 2 ) # Self is implicitly passed. print ( s. field ) s. div ( 2 ) # Self is implicitly passed. print ( s. field ) s. sub ( 2 ) # Self is implicitly passed. print ( s. field ) Output 5.0 7.0 14.0 7.0 5.0

How to create Static Class variables? Variables declared inside the class definition, but not inside a method are class or static variables. Example class Employee: age = 25 print ( Employee. age ) e = Employee ( ) print ( e. age ) e. age = 30 print ( Employee. age ) # 25 print ( e. age ) # 30 Output 25 25 25 30

Create multiple Class variables pass in argument list Example class Employee ( object ) : def __init__ ( self , **kwargs ) : for key in kwargs: setattr ( self , key , kwargs [ key ] ) emp = Employee ( age = 25 , name = "John Doe" ) print ( emp. age ) print ( emp. name ) Output 25 John Doe

What is the difference between __init__ and __call__? __init__ would be treated as Constructor where as __call__ methods can be called with objects any number of times. Both __init__ and __call__ functions do take default arguments. Example class Counter: def __init__ ( self ) : self ._weights = [ ] for i in range ( 0 , 2 ) : self ._weights. append ( 1 ) print ( str ( self ._weights [ - 2 ] ) + " No. from __init__" ) def __call__ ( self , t ) : self ._weights = [ self ._weights [ - 1 ] , self ._weights [ - 1 ] + self ._weights [ - 1 ] ] print ( str ( self ._weights [ - 1 ] ) + " No. from __call__" ) num_count = Counter ( ) for i in range ( 0 , 4 ) : num_count ( i ) Output 1 No. from __init__ 2 No. from __call__ 4 No. from __call__ 8 No. from __call__ 16 No. from __call__

Example using __new__ and __init__ Use __new__ when you need to control the creation of a new instance. Use __init__ when you need to control initialization of a new instance. Example class Shape: def __new__ ( cls , sides , *args , **kwargs ) : if sides == 3 : return Triangle ( *args , **kwargs ) else : return Square ( *args , **kwargs ) class Triangle: def __init__ ( self , base , height ) : self . base = base self . height = height def area ( self ) : return ( self . base * self . height ) / 2 class Square: def __init__ ( self , length ) : self . length = length def area ( self ) : return self . length * self . length a = Shape ( sides = 3 , base = 2 , height = 12 ) b = Shape ( sides = 4 , length = 2 ) print ( str ( a.__class__ ) ) print ( a. area ( ) ) print ( str ( b.__class__ ) ) print ( b. area ( ) ) Output class '__main__.Triangle' 12.0 class '__main__.Square' 4

Iteration Overloading Methods The __iter__ returns the iterator object and is implicitly called at the start of loops. The __next__ method returns the next value and is implicitly called at each loop increment. __next__ raises a StopIteration exception when there are no more value to return, which is implicitly captured by looping constructs to stop iterating. Example class Counter: def __init__ ( self , low , high ) : self . current = low self . high = high def __iter__ ( self ) : return self def __next__ ( self ) : if self . current > self . high : raise StopIteration else : self . current + = 1 return self . current - 1 for num in Counter ( 5 , 15 ) : print ( num ) Output 5 6 .. .. 15

Reverse a string using Iterator Iterators implement a __next__ method that returns individual items, and a __iter__ method that returns self . Example class Reverse: def __init__ ( self , data ) : self . data = data self . index = len ( data ) def __iter__ ( self ) : return self def __next__ ( self ) : if self . index == 0 : raise StopIteration self . index = self . index - 1 return self . data [ self . index ] test = Reverse ( 'Python' ) for char in test : print ( char ) Output n o h t y P

Example of __reversed__ Magic method Iterables can implement __reversed__ to return an iterator that goes backwards. Example class Count: def __init__ ( self , start , end ) : self . start = start self . end = end self . current = None def __iter__ ( self ) : self . current = self . start while self . current < self . end : yield self . current self . current + = 1 def __next__ ( self ) : if self . current is None : self . current = self . start if self . current > self . end : raise StopIteration else : self . current + = 1 return self . current - 1 def __reversed__ ( self ) : self . current = self . end while self . current >= self . start : yield self . current self . current - = 1 obj1 = Count ( 0 , 5 ) for i in obj1: print ( i ) obj2 = reversed ( obj1 ) for i in obj2: print ( i ) Output 0 1 2 .... 2 1 0

Indexing and Slicing with __getitem__ and __setitem__ Example class Counter ( object ) : def __init__ ( self , floors ) : self ._floors = [ None ] *floors def __setitem__ ( self , floor_number , data ) : self ._floors [ floor_number ] = data def __getitem__ ( self , floor_number ) : return self ._floors [ floor_number ] index = Counter ( 4 ) index [ 0 ] = 'ABCD' index [ 1 ] = 'EFGH' index [ 2 ] = 'IJKL' index [ 3 ] = 'MNOP' print ( index [ 2 ] ) Output IJKL

Attribute assignment using __getattr__ and __setattr__ The __getattr__ method intercepts attribute references and the __setattr__ intercepts all attribute assignments. Example class Employee ( object ) : def __init__ ( self , data ) : super ( ) . __setattr__ ( 'data' , dict ( ) ) self . data = data def __getattr__ ( self , name ) : if name in self . data : return self . data [ name ] else : return 0 def __setattr__ ( self , key , value ) : if key in self . data : self . data [ key ] = value else : super ( ) . __setattr__ ( key , value ) emp = Employee ( { 'age' : 23 , 'name' : 'John' } ) print ( emp. age ) print ( emp. name ) print ( emp. data ) print ( emp. salary ) emp. salary = 50000 print ( emp. salary ) Output 23 John {'age': 23, 'name': 'John'} 0 50000

What is the __del__ method and how to call it? The __del__ is a finalizer. It is called when an object is garbage collected which happens at some point after all references to the object have been deleted. Example class Employee ( ) : def __init__ ( self , name = 'John Doe' ) : print ( 'Hello ' + name ) self . name = name def developer ( self ) : print ( self . name ) def __del__ ( self ) : print ( 'Good Bye ' + self . name ) emp = Employee ( 'Mark' ) print ( emp ) emp = 'Rocky' print ( emp ) Output Hello Mark Good Bye Mark Rocky

How to create Private members of class? If the name of a Python function, class method, or attribute starts with (but doesn't end with) two underscores, it's private; everything else is public. Example class Test ( object ) : __private_var = 100 public_var = 200 def __private_func ( self ) : print ( 'Private Function' ) def public_func ( self ) : print ( 'Public Function' ) print ( self . public_var ) def call_private ( self ) : self .__private_func ( ) print ( self .__private_var ) t = Test ( ) print ( t. call_private ( ) ) print ( t. public_func ( ) ) Output Private Function 100 None Public Function 200 None

Give an example of encapsulation in Python The wrapping up of data and functions into a single unit (called class) is known as encapsulation. Data encapsulation is the most striking feature of a class. The data is not accessible to the outside world, and only those functions, which are wrapped in the class, can access it. These functions provide the interface between the object’s data and the program. This insulation of the data from direct access by the program is called data hiding or information hiding. Example class Encapsulation: __name = None def __init__ ( self , name ) : self .__name = name def get_name ( self ) : return self .__name pobj = Encapsulation ( 'Rocky' ) print ( pobj. get_name ( ) ) Output Rocky

Give an example of Composition in Python In composition one of the classes is composed of one or more instance of other classes. In other words one class is container and other class is content and if you delete the container object then all of its contents objects are also deleted. Example class Salary: def __init__ ( self , pay ) : self . pay = pay def get_total ( self ) : return ( self . pay * 12 ) class Employee: def __init__ ( self , pay , bonus ) : self . pay = pay self . bonus = bonus self . obj_salary = Salary ( self . pay ) def annual_salary ( self ) : return "Total: " + str ( self . obj_salary . get_total ( ) + self . bonus ) obj_emp = Employee ( 600 , 500 ) print ( obj_emp. annual_salary ( ) ) Output Total: 7700

Give an example of Aggregation in Python Aggregation is a week form of composition. If you delete the container object contents objects can live without container object. Example class Salary: def __init__ ( self , pay ) : self . pay = pay def get_total ( self ) : return ( self . pay * 12 ) class Employee: def __init__ ( self , pay , bonus ) : self . pay = pay self . bonus = bonus def annual_salary ( self ) : return "Total: " + str ( self . pay . get_total ( ) + self . bonus ) obj_sal = Salary ( 600 ) obj_emp = Employee ( obj_sal , 500 ) print ( obj_emp. annual_salary ( ) ) Output Total: 7700

Single, Multiple and Multi-level Inheritance Example # Single inheritence class Apple: manufacturer = 'Apple Inc' contact_website = 'www.apple.com/contact' name = 'Apple' def contact_details ( self ) : print ( 'Contact us at ' , self . contact_website ) class MacBook ( Apple ) : def __init__ ( self ) : self . year_of_manufacture = 2018 def manufacture_details ( self ) : print ( 'This MacBook was manufactured in {0}, by {1}.' . format ( self . year_of_manufacture , self . manufacturer ) ) macbook = MacBook ( ) macbook. manufacture_details ( ) # Multiple inheritence class OperatingSystem: multitasking = True name = 'Mac OS' class MacTower ( OperatingSystem , Apple ) : def __init__ ( self ) : if self . multitasking is True : print ( 'Multitasking system' ) # if there are two superclasses with the sae attribute name # the attribute of the first inherited superclass will be called # the order of inhertence matters print ( 'Name: {}' . format ( self . name ) ) mactower = MacTower ( ) # Multilevel inheritence class MusicalInstrument: num_of_major_keys = 12 class StringInstrument ( MusicalInstrument ) : type_of_wood = 'Tonewood' class Guitar ( StringInstrument ) : def __init__ ( self ) : self . num_of_strings = 6 print ( 'The guitar consists of {0} strings,' + 'it is made of {1} and can play {2} keys.' . format ( self . num_of_strings , self . type_of_wood , self . num_of_major_keys ) ) guitar = Guitar ( ) Output This MacBook was manufactured in 2018, by Apple Inc. Multitasking system Name: Mac OS The guitar consists of 6 strings, it is made of Tonewood and can play 12 keys.

How to get the parents classes of a class? Example class A ( object ) : pass class B ( object ) : pass class C ( A , B ) : pass print ( C.__bases__ ) Output (< class '__main__.A' >, < class '__main__.B' >)

Polymorphism Polymorphism allows us to define methods in the child class with the same name as defined in their parent class. Example # Creating a shape Class class Shape: width = 0 height = 0 # Creating area method def area ( self ) : print ( "Parent class Area ... " ) # Creating a Rectangle Class class Rectangle ( Shape ) : def __init__ ( self , w , h ) : self . width = w self . height = h # Overridding area method def area ( self ) : print ( "Area of the Rectangle is : " , self . width * self . height ) # Creating a Triangle Class class Triangle ( Shape ) : def __init__ ( self , w , h ) : self . width = w self . height = h # Overridding area method def area ( self ) : print ( "Area of the Triangle is : " , ( self . width * self . height ) / 2 ) rectangle = Rectangle ( 10 , 20 ) triangle = Triangle ( 2 , 10 ) rectangle. area ( ) triangle. area ( ) Output Area of the Rectangle is : 200 Area of the Triangle is : 10.0

How to access private members in Child class? Example class Human ( ) : # Private var __privateVar = "this is __private variable" # Constructor method def __init__ ( self ) : self . className = "Human class constructor" self .__privateVar = "this is redefined __private variable" # Public method def showName ( self , name ) : self . name = name return self .__privateVar + " " + name # Private method def __privateMethod ( self ) : return "Private method" # Public method that returns a private variable def showPrivate ( self ) : return self .__privateMethod ( ) def showProtecded ( self ) : return self ._protectedMethod ( ) class Male ( Human ) : def showClassName ( self ) : return "Male" def showPrivate ( self ) : return self .__privateMethod ( ) def showProtected ( self ) : return self ._protectedMethod ( ) class Female ( Human ) : def showClassName ( self ) : return "Female" def showPrivate ( self ) : return self .__privateMethod ( ) human = Human ( ) print ( human. className ) print ( human. showName ( "Vasya" ) ) print ( human. showPrivate ( ) ) male = Male ( ) print ( male. className ) print ( male. showClassName ( ) ) female = Female ( ) print ( female. className ) print ( female. showClassName ( ) ) Output Human class constructor this is redefined __private variable Vasya Private method Human class constructor Male Human class constructor Female

What is an abstract class? Abstract classes are classes that contain one or more abstract methods. An abstract method is a method that is declared, but contains no implementation. Abstract classes may not be instantiated, and require sub-classes to provide implementations for the abstract methods Example from abc import ABC , abstractmethod class AbstractClass ( ABC ) : def __init__ ( self , value ) : self . value = value super ( ) . __init__ ( ) @ abstractmethod def eat ( self ) : pass class Parents ( AbstractClass ) : def eat ( self ) : return "Eat solid food " + str ( self . value ) + " times each day." class Babies ( AbstractClass ) : def eat ( self ) : return "Milk only " + str ( self . value ) + " times or more each day." food = 3 adult = Parents ( food ) print ( 'Adult' ) print ( adult. eat ( ) ) infant = Babies ( food ) print ( 'Infants' ) print ( infant. eat ( ) ) Output Adult Eat solid food 3 times each day. Infants Milk only 3 times or more each day.

Create an Abstract class to override default constructor Making the __init__ an abstract method



Example from abc import ABCMeta , abstractmethod class AbstractClass ( object , metaclass = ABCMeta ) : @ abstractmethod def __init__ ( self , n ) : self . n = n class Employee ( AbstractClass ) : def __init__ ( self , salary , name ) : self . salary = salary self . name = name emp1 = Employee ( 10000 , "John Doe" ) print ( emp1. salary ) print ( emp1. name ) Output 10000 John Doe

Make an abstract class inherit from another abstract class A class that is derived from an abstract class cannot be instantiated unless all of its abstract methods are overridden. Example from abc import ABC , abstractmethod class A ( ABC ) : def __init__ ( self , username ) : self . username = username super ( ) . __init__ ( ) @ abstractmethod def name ( self ) : pass class B ( A ) : @ abstractmethod def age ( self ) : pass class C ( B ) : def name ( self ) : print ( self . username ) def age ( self ) : return c = C ( 'Test1234' ) c. name ( ) Output Test1234

What does super do in Python? In a class hierarchy with single inheritance, super can be used to refer to parent classes without naming them explicitly, thus making the code more maintainable. This use closely parallels the use of super in other programming languages. Example class A ( object ) : def __init__ ( self , profession ) : print ( profession ) class B ( A ) : def __init__ ( self ) : print ( 'John Doe' ) super ( ) . __init__ ( 'Developer' ) b = B ( ) Output John Doe Developer

How super() works with __init__() method in multiple inheritance? super support cooperative multiple inheritance in a dynamic execution environment. This use case is unique to Python and is not found in statically compiled languages or languages that only support single inheritance. Example class F: def __init__ ( self ) : print ( 'F%s' % super ( ) . __init__ ) super ( ) . __init__ ( ) class G: def __init__ ( self ) : print ( 'G%s' % super ( ) . __init__ ) super ( ) . __init__ ( ) class H: def __init__ ( self ) : print ( 'H%s' % super ( ) . __init__ ) super ( ) . __init__ ( ) class E ( G , H ) : def __init__ ( self ) : print ( 'E%s' % super ( ) . __init__ ) super ( ) . __init__ ( ) class D ( E , F ) : def __init__ ( self ) : print ( 'D%s' % super ( ) . __init__ ) super ( ) . __init__ ( ) class C ( E , G ) : def __init__ ( self ) : print ( 'C%s' % super ( ) . __init__ ) super ( ) . __init__ ( ) class B ( C , H ) : def __init__ ( self ) : print ( 'B%s' % super ( ) . __init__ ) super ( ) . __init__ ( ) class A ( D , B , E ) : def __init__ ( self ) : print ( 'A%s' % super ( ) . __init__ ) super ( ) . __init__ ( ) a = A ( ) print ( a ) Output A bound method D.__init__ of __main__.A object at 0x000000000369CFD0 D bound method B.__init__ of __main__.A object at 0x000000000369CFD0 B bound method C.__init__ of __main__.A object at 0x000000000369CFD0 C bound method E.__init__ of __main__.A object at 0x000000000369CFD0 E bound method G.__init__ of __main__.A object at 0x000000000369CFD0 G bound method H.__init__ of __main__.A object at 0x000000000369CFD0 H bound method F.__init__ of __main__.A object at 0x000000000369CFD0 F method-wrapper '__init__' of A object at 0x000000000369CFD0 __main__.A object at 0x000000000369CFD0

How to use super with a class method? When calling super to resolve to a parent's version of a class-method, instance method, or static-method, we want to pass the current class whose scope we are in as the first argument, to indicate which parent's scope we're trying to resolve to, and as a second argument the object of interest to indicate which object we're trying to apply that scope to. Example class A ( object ) : @ classmethod def name ( self , employee ) : print ( 'Employee Name: ' , employee ) class B ( A ) : @ classmethod def name ( self , employee ) : super ( B , self ) . name ( employee ) B. name ( 'John Doe' ) Output Employee Name: John Doe

What does mro do? mro stands for Method Resolution Order. It returns a list of types the class is derived from, in the order they are searched for methods. Example class A ( object ) : def dothis ( self ) : print ( 'From A class' ) class B1 ( A ) : def dothis ( self ) : print ( 'From B1 class' ) pass class B2 ( object ) : def dothis ( self ) : print ( 'From B2 class' ) pass class B3 ( A ) : def dothis ( self ) : print ( 'From B3 class' ) # Diamond inheritance class D1 ( B1 , B3 ) : pass class D2 ( B1 , B2 ) : pass d1_instance = D1 ( ) d1_instance. dothis ( ) print ( D1.__mro__ ) d2_instance = D2 ( ) d2_instance. dothis ( ) print ( D2.__mro__ ) Output From B1 class (class '__main__.D1', class '__main__.B1', ) From B1 class (class '__main__.D2', class '__main__.B1', , class '__main__.B2', class 'object')

What are metaclasses in Python? A metaclass is the class of a class. A class defines how an instance of the class (i.e. an object) behaves while a metaclass defines how a class behaves. A class is an instance of a metaclass. A metaclass is most commonly used as a class-factory. When you create an object by calling the class, Python creates a new class (when it executes the 'class' statement) by calling the metaclass. However, metaclasses actually define the type of a class, not just a factory for it, so you can do much more with them. Example def _addMethod ( fldName , clsName , verb , methodMaker , dict ) : compiledName = _getCompiledName ( fldName , clsName ) methodName = _getMethodName ( fldName , verb ) dict [ methodName ] = methodMaker ( compiledName ) def _getCompiledName ( fldName , clsName ) : if fldName [ : 2 ] == "__" and fldName [ - 2 : ] != "__" : return "_%s%s" % ( clsName , fldName ) else : return fldName def _getMethodName ( fldName , verb ) : s = fldName. lstrip ( "_" ) return verb + s. capitalize ( ) def _makeGetter ( compiledName ) : return lambda self : self . __dict__ [ compiledName ] def _makeSetter ( compiledName ) : return lambda self , value: setattr ( self , compiledName , value ) class Accessors ( type ) : def __new__ ( cls , clsName , bases , dict ) : for fldName in dict . get ( "_READ" , [ ] ) + dict . get ( "_READ_WRITE" , [ ] ) : _addMethod ( fldName , clsName , "get" , _makeGetter , dict ) for fldName in dict . get ( "_WRITE" , [ ] ) + dict . get ( "_READ_WRITE" , [ ] ) : _addMethod ( fldName , clsName , "set" , _makeSetter , dict ) return type . __new__ ( cls , clsName , bases , dict ) class Employee ( object , metaclass = Accessors ) : _READ_WRITE = [ 'name' , 'salary' , 'title' , 'bonus' ] def __init__ ( self , name , salary , title , bonus = 0 ) : self . name = name self . salary = salary self . title = title self . bonus = bonus b = Employee ( 'John Doe' , 25000 , 'Developer' , 5000 ) print ( 'Name:' , b. getName ( ) ) print ( 'Salary:' , b. getSalary ( ) ) print ( 'Title:' , b. getTitle ( ) ) print ( 'Bonus:' , b. getBonus ( ) ) Output Name: John Doe Salary: 25000 Title: Developer Bonus: 5000

What are concrete use-cases for metaclasses? Metaclass allows you to separate what the class does from the details of how it's created. The metaclass and class are each responsible for one thing. You can write the code once in a metaclass, and use it for customizing several classes call behavior without worrying about multiple inheritance. Subclasses can override behavior in their __new__ method, but __call__ on a metaclass doesn't have to even call __new__ at all. If there is setup work, you can do it in the __new__ method of the metaclass, and it only happens once, instead of every time the class is called. Example class UpperAttrNameMetaClass ( type ) : def __new__ ( cls , clsname , bases , attrdict , *args , **kwargs ) : print ( '1. Create a new type, from ' + ' UpperAttrNameMetaClass.__new__' ) new_attrs = dict ( ) for attr , value in attrdict. items ( ) : if not callable ( value ) and not str ( attr ) . startswith ( '__' ) : new_attrs [ attr. upper ( ) ] = value else : new_attrs [ attr ] = value cls_obj = super ( ) . __new__ ( cls , clsname , bases , new_attrs , *args , **kwargs ) return cls_obj def __init__ ( self , clsname , bases , attrdict ) : self . test = 'test' super ( ) . __init__ ( clsname , bases , attrdict ) print ( '2. Initialize new type, increase test attribute,' + 'from UpperAttrNameMetaClass.__init__' ) def __call__ ( self , *args , **kwargs ) : print ( '3. Instantiate the new class,' + ' from UpperAttrNameMetaClass.__call__' ) new_obj = self . __new__ ( self , *args , **kwargs ) new_obj. __init__ ( *args , **kwargs ) return new_obj class ObjectNoInitMetaClass ( type ) : def __call__ ( cls , *args , **kwargs ) : if len ( args ) : raise TypeError ( 'Must use keyword argument ' + ' for key function' ) new_obj = cls. __new__ ( cls ) for k , v in kwargs. items ( ) : setattr ( new_obj , k. upper ( ) , v ) return new_obj class Pig ( object , metaclass = UpperAttrNameMetaClass ) : size = 'Big' def __new__ ( cls , *args , **kwargs ) : print ( '4. Call __new__ in the __call__ of the metaclass,' + ' from Pig.__new__' ) obj = object . __new__ ( cls ) return obj def __init__ ( self ) : print ( '5. After the new object is instantiated in ' + 'the __call__ of the metaclass,the object is promoted,' + ' from Pig.__init__' ) self . name = 'Mark' def talk ( self ) : print ( self . name ) Pig ( ) . talk ( ) print ( Pig. __dict__ ) print ( Pig. SIZE ) class AnyOne ( metaclass = ObjectNoInitMetaClass ) : pass foo = AnyOne ( name = 'John' , age = 28 ) print ( foo. NAME , foo. AGE ) print ( foo. __dict__ ) Output 1. Create a new type, from UpperAttrNameMetaClass.__new__ 2. Initialize new type, increase test attribute,from UpperAttrNameMetaClass.__init__ 3. Instantiate the new class, from UpperAttrNameMetaClass.__call__ 4. Call __new__ in the __call__ of the metaclass, from Pig.__new__ 5. After the new object is instantiated in the __call__ of the metaclass,the object is promoted, from Pig.__init__ Mark {'__doc__': None, 'test': 'test', '__weakref__': , 'SIZE': 'Big', '__init__': , '__dict__': , '__module__': '__main__', '__new__': , 'talk': } Big John 28 {'AGE': 28, 'NAME': 'John'}

Singleton class using Metaclass A metaclass is a class used to create a class. Metaclasses are usually sub classes of the type class, which redefines class creation protocol methods in order to customize the class creation call issued at the end of a class statement. Example class SingleInstanceMetaClass ( type ) : def __init__ ( self , name , bases , dic ) : self .__single_instance = None super ( ) . __init__ ( name , bases , dic ) def __call__ ( cls , *args , **kwargs ) : if cls.__single_instance: return cls.__single_instance single_obj = cls. __new__ ( cls ) single_obj. __init__ ( *args , **kwargs ) cls.__single_instance = single_obj return single_obj class Setting ( metaclass = SingleInstanceMetaClass ) : def __init__ ( self ) : self . db = 'MySQL' self . port = 3306 bar1 = Setting ( ) bar2 = Setting ( ) print ( bar1 is bar2 ) print ( bar1. db , bar1. port ) bar1. db = 'ORACLE' print ( bar2. db , bar2. port ) Output True MySQL 3306 ORACLE 3306

What is the difference between @staticmethod and @classmethod? @staticmethod function is nothing more than a function defined inside a class. It is callable without instantiating the class first. It’s definition is immutable via inheritance. @classmethod function also callable without instantiating the class, but its definition follows Sub class, not Parent class, via inheritance. Example class Employee: @ classmethod def classmthd ( *args ) : return args @ staticmethod def staticmthd ( *args ) : return args print ( Employee. classmthd ( ) ) print ( Employee. classmthd ( 'test' ) ) print ( Employee. staticmthd ( ) ) print ( Employee. staticmthd ( 'test' ) ) Output (class '__main__.Employee',) (class '__main__.Employee', 'test') () ('test',)

What are decorators in Python? Python decorators are just plain functions or other callables which take as single argument the function or class to be decorated. As such you can use many ordinary functions as decorators and vice versa. Example def message ( param1 , param2 ) : def wrapper ( wrapped ) : class WrappedClass ( wrapped ) : def __init__ ( self ) : self . param1 = param1 self . param2 = param2 super ( WrappedClass , self ) . __init__ ( ) def get_message ( self ) : return "message %s %s" % ( self . param1 , self . param2 ) return WrappedClass return wrapper @ message ( "param1" , "param2" ) class Pizza ( object ) : def __init__ ( self ) : pass pizza_with_message = Pizza ( ) print ( pizza_with_message. get_message ( ) ) Output message param1 param2

How to make a chain of function decorators? Decorators have a very explicit syntax, which makes them easier to spot than helper function calls that may be arbitrarily far-removed from the subject functions or classes. Decorators offer some advantages in terms of both code maintenance and consistency. Example def benchmark ( func ) : """ A decorator that prints the time a function takes to execute. """ import time def wrapper ( *args , **kwargs ) : t = time . clock ( ) res = func ( *args , **kwargs ) print ( "{0} {1}" . format ( func.__name__ , time . clock ( ) -t ) ) return res return wrapper def logging ( func ) : """ A decorator that logs the activity of the script. (it actually just prints it, but it could be logging!) """ def wrapper ( *args , **kwargs ) : res = func ( *args , **kwargs ) print ( "{0} {1} {2}" . format ( func.__name__ , args , kwargs ) ) return res return wrapper def counter ( func ) : """ A decorator that counts and prints the number of times a function has been executed """ def wrapper ( *args , **kwargs ) : wrapper. count = wrapper. count + 1 res = func ( *args , **kwargs ) print ( "{0} has been used: {1}x" . format ( func.__name__ , wrapper. count ) ) return res wrapper. count = 0 return wrapper @ counter @ benchmark @ logging def letter_range ( start , stop , step = 1 ) : start = ord ( start. lower ( ) ) stop = ord ( stop. lower ( ) ) for str_lst in range ( start , stop , step ) : yield chr ( str_lst ) print ( list ( letter_range ( "a" , "f" ) ) ) print ( '

' ) print ( list ( letter_range ( "m" , "z" , 2 ) ) ) Output letter_range ('a', 'f') {} wrapper 0.0009437184107374183 wrapper has been used: 1x ['a', 'b', 'c', 'd', 'e'] letter_range ('m', 'z', 2) {} wrapper 3.131164480070134e-05 wrapper has been used: 2x ['m', 'o', 'q', 's', 'u', 'w', 'y']

Decorator for both class methods and functions Function decorators can also be used to manage function objects and Class decorators can also be used to manage class objects directly. Example def deco ( func ) : def inner ( *args ) : print ( 'Decorator: args={}' . format ( args ) ) func ( *args ) return inner class Class: @ deco def class_method ( self , param ) : print ( 'Parameter is {}' . format ( param ) ) @ deco def static_function ( a , b , c ) : print ( '{} {} {}' . format ( a , b , c ) ) Class ( ) . class_method ( 25000 ) static_function ( 'Australia' , 'Germany' , 'London' ) Output Decorator: args=( , 25000) Parameter is 25000 Decorator: args=('Australia', 'Germany', 'London') Australia Germany London