Mixin mechanism
Mixin means mix in. In fact, this concept is also for the optimization of some codes
class Vehicle: # vehicle def fly(self): print("I can fly") class Plane(Vehicle): # aircraft pass class Helicopter(Vehicle): # helicopter pass class Car(Vehicle): # automobile pass ''' '''
Although the car is a means of transportation, it can't fly. It's unreasonable to inherit this way so that the car can fly
However, the method of directly writing flying in aircraft and helicopter makes the code reusable. When there are more classes (there are many flying vehicles, so it is very troublesome to write a flying method for one)
In order to solve this problem, Python provides Mixins mechanism. In short, Mixins mechanism refers to the function of subclasses mixing different classes, and these classes adopt a unified naming convention (such as Mixin suffix), so as to identify that these classes are only used to mix functions
Mixins mechanism is multi inheritance in essence, which is actually a convention
class Vehicle: pass class FlyableMixin: def fly(self): print("I can fly") # Encapsulate it into a function class alone, and remind yourself that it is a mixture of subclasses (function class) with Mixin. It is OK for flying vehicles to directly inherit this class class Plane(FlyableMixin, Vehicle): # Civil aircraft pass class Helicopter(FlyableMixin, Vehicle): # helicopter pass class Car(Vehicle): # automobile pass
Using some kind of specification (such as constant naming specification and the previous hidden attribute specification) to solve specific problems is a common routine of python
Precautions for Mixin mechanism:
Use Mixin classes to implement multiple inheritance with great care
- It represents a function, not an item. It is generally named with the suffix of mixin, able and able
- It must have a single function. If there are multiple functions, write multiple Mixin classes. A class can inherit multiple mixins
- Mixin class is just a function. It can work even if it is not inherited in time, but it lacks a function
- Mixins is a good way to reuse code from multiple classes, but when the inheritance level becomes more, the readability of the code becomes worse
Parent class method reuse
Let's continue to optimize our code
class People: def __init__(self,name,age): self.name=name self.age=age class Teacher(People): def __init__(self,name,age,work_period): self.name=name self.age=age self.work_period=work_period def teach(self): print('Teaching and educating people') """ When initializing the above teacher class, because there are many duplicate variables with the initialization of the parent class, you can directly use the initialization method of the parent class """ # 1. Directly call the method of the parent class with the class name class Teacher(People): def __init__(self,name,age,work_period): People.__init__(self,name,age) # Class name initialization directly self.work_period=work_period # 2.super method class Teacher(People): def __init__(self,name,sex,age,title): super().__init__(name,age,sex) # The binding method is called, and self is automatically passed in self.title=title # In Python 2, the use of super needs to be completely written as super (its own class name, self), while in Python 3, it can be abbreviated as super() # Mode 1 has nothing to do with inheritance, while mode 2's super() depends on inheritance. Even if there is no direct inheritance relationship, super() will continue to look for it later according to MRO
Combination of classes
The properties between classes may refer to each other
class Course: # Courses def __init__(self,name,price): self.name=name self.price=price def tell_info(self): print('<%s %s>' %(self.name,self.price)) class BirthDate: def __init__(self,year,mon,day): self.year=year self.mon=mon self.day=day def tell_birth(self): print('<%s-%s-%s>' %(self.year,self.mon,self.day)) class People: def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age # The Teacher class reuses People's code through inheritance # Reuse the code of the BirthDate class and Course class through composition class Teacher(People): # Teacher class def __init__(self,name,sex,age,title,year,mon,day): super().__init__(name,age,sex) self.birth=BirthDate(year,mon,day) # Use the properties of other classes directly in the class self.courses=[] # After instantiation, add the Course class object to the list def teach(self): print('%s is teaching' %self.name) python=Course('python',3000) linux=Course('linux',5000) teacher1=Teacher('lilei','female',28,'tutor',1990,3,23) # teacher1 has two courses teacher1.courses.append(python) teacher1.courses.append(linux) # Reuse the functions of the BirthDate class teacher1.birth.tell_birth() # Reuse the function of Course class for obj in teacher1.courses: obj.tell_info()