19.4.2 methods related to members
1.__getattribute__ Trigger mechanism: automatically trigger when accessing object members, regardless of whether object members exist or not Function: you can process data when obtaining object members Parameter: one self Accept object, one item The name of the member receiving the current access Return value: optional. The returned value is the result of access Note: in the current magic method, access to members of the current object is prohibited, which will trigger recursion To access members in the current method, you must use object.__getattribute__(self,item) 2. __getattr__ Trigger mechanism: automatically triggered when accessing a member that does not exist in the object effect: Prevent errors when accessing nonexistent members, or assign values to nonexistent members Parameter: one self Accept object, one item The name of the member receiving the current access Return value: optional Note: when present__getattribute__This method is executed when 3. __setattr__ Trigger mechanism: automatically triggered when assigning values to object members, including modification and addition effect: You can restrict or manage the addition and modification of object members Parameter: 1.self Accept object 2.Set member name 3.Set member value Return value: None Note: direct assignment to the current object member is prohibited in the current method, otherwise recursion will be triggered To assign a value, use object.__setattr__(self,key,val) 4. __delattr__ Trigger mechanism: automatically triggered when an object member is deleted effect: You can restrict the deletion of object members and prevent errors when deleting non-existent members Parameter: 1.self Accept object 2.Deleted member name Return value: None Note: in the current method, it is forbidden to directly delete object members, which will trigger recursion To delete, use object.__delattr__(self,item)
- try: except
class Person(): name = 'zhang' age = 40 sex = 'male' def __init__(self,n,a,s): self.name = n self.age = a self.sex = s def say(self): print('make a speech') # Automatically triggered when an object member is obtained def __getattribute__(self, item): # print(self.name) does not allow this operation, and an error will be reported # Judge whether there are attributes, pay attention!! # try: res = object.__getattribute__(self,item) # Method can process the accessed member data return res[0]+'**'+res[-1] # except: # return False # Automatically triggered when a member that does not exist is accessed def __getattr__(self, item): print(item) return False def __setattr__(self, key, value): print(self,key,value) object.__setattr__(self,key,value) def __delattr__(self, item): print(item) z = Person('zhangs',45,'male') print(z.one) z.one = 'this is new' print(z.one) del z.one
Access member call order!!!
1.__getattribute__
2. Data descriptor
3. Call the member of the current object
4. Call the members of the current class
5. Non data descriptor
6. Call the member of the parent class
7.__getattr__
- The above steps are the sequence of calling a member. The previous one can be called successfully, and the later one will not be executed
Data descriptor: a class with three magic methods at the same time is
Non data descriptor: not both
19.5 descriptors
When a class contains one or all of the three magic methods (_get_, _set_, _delete_), the class is called Descriptor Class
19.5.1 basic syntax of descriptor
-
effect:
Perform a detailed management operation (get, assign, delete) on a member of a class
Descriptors represent the operations of members in a class. They can only be defined as class attributes and belong to a class -
Use format:
Assign a descriptor class to a member attribute in a class that needs a proxy
A member in a class is an object of a descriptor class
When operating on a member of this class, it can be understood as operating on another object
# Define descriptor class class Personname(): __name = 'name1' def __get__(self, instance, owner): return self.__name def __set__(self, instance, value): self.__name = value # be careful! def __del__(self): # del self.__name print('Deletion not allowed') class Person(): # Give an attribute in the class to the descriptor class to implement name = Personname() z = Person() z.name = 'zhangsan' print(z.name)
19.5.2 application cases of descriptors
- Define a student class and record the student's ID, name and score
- Students are required to score only 0-100
# Limit score range ''' Method 1:__init__Medium judgment if score in range(0,101): self.score = score This method is only valid when the object is initialized!! Method 2:__setattr__ def __setattr__(self, key, value): # Check whether the score is assigned if key == 'score': if value in range(0, 101): object.__setattr__(self, key, value) else: print('wrong') else: object.__setattr__(self,key,value) If the student scores more than one, and the code is concise? Method 3: use descriptor class proxy 1,definition score Descriptor Class 2,Put students in the class score This member is delegated to the descriptor class 3,Just assign and get the score in the descriptor class of the agent ''' # Use descriptor class proxy score attribute class Score(): __score = 0 def __get__(self, instance, owner): return self.__score def __set__(self, instance, value): if value in range(101): self.__score = value else: print('wrong score') class Student(): score = Score() def __init__(self,id,name,score): self.id = id self.name = name self.score = score def Returnme(self): info = f''' Student ID : {self.id} Student Name : {self.name} Student Score : {self.score} ''' print(info) # Instantiate object one = Student('20211001','wangwu',99) one.Returnme() one.score = 120 one.score = 100 one.Returnme()
19.5.3 three definitions of descriptors
1. Format 1: implemented by defining descriptors, recommend
class ScoreManage(): def __get__(self, instance, owner): pass def __set__(self, instance, value): pass def __delete__(self, instance): pass class Student(): score = ScoreManage()
2. Format 2: use property Function implementation
class Student(): def getscore(self): print('getscore') def setscore(self,value): print('setscore',value) def delscore(self): print('delscore') # Specify three corresponding methods in the property function (corresponding in fixed order!), 1__get__2,__set__3,__del__ score = property(getscore,setscore,delscore) zz = Student() print(zz.score) # getscore /n None zz.score = 200 del zz.score
3. Format 3: use @ property Decorator syntax implementation
class Student(): __score = 0 @property def score(self): print('getscore') return self.__score @score.setter def score(self,value): print('setscore',value) self.__score = value @score.deleter def score(self): print('delscore') del self.__score zs = Student() zs.score print(zs.score) zs.score = 122 print(zs.score) del zs.score
19.6 design mode
In order to complete a function or requirement, predecessors summarized and summarized the code steps and code design according to experience and summary, which has become a classic mode to realize a requirement.
Design pattern is not a fixed code format, but an object-oriented programming design
19.6.1 single case (single state) design mode
In the current script, the same class can only create one object to use
''' Interfere with unlimited use of classes Consider the case of realizing a single example: Singleton and marriage law, especially like, a person can only have one legal marriage object: How to complete in society? To register with the Civil Affairs Bureau, you need to check the household register to see if it is married. If you are unmarried, you can register 1.You need a method to control the creation of objects Construction method __new__ 2.In this method, it is necessary to detect whether there is an object. In the construction method, it is necessary to add judgment conditions An identifier is required to store and indicate whether there are objects Create an attribute and store it. The default value is None 3.You can detect and judge in the method of creating objects If there is no object, the object is created, stored, and returned If yes, the object is returned directly without creating a new object ''' class Demo(): # 2. Define private attribute storage object __obj = None # 1. Define construction method def __new__(cls, *args, **kwargs): # 3. In the process of creating objects, judge whether there are objects if not cls.__obj: # Judge if there is no object, create and store it cls.__obj = object.__new__(cls) return cls.__obj a = Demo() b = Demo() print(a) print(b)
Note: memorize!!
19.6.2 mix in hybrid design mode
''' The vehicle class includes cars, planes, helicopters, etc. How to define the flight function Vehicles and aircraft But 1.Multiple class inheritance, violation'is-a' 2.Aircraft are easy to misunderstand Solution: define the aircraft class as a Mixin Mixed class It is equivalent to taking the aircraft class as an extended function to extend other classes ''' class Vehicle(): def carry(self): print('transfer the groceries') def carry2(self): print('transfer passengers') class FlyingMixin(): def fly(self): print('fly in the sky') class Car(Vehicle): pass class Airplane(Vehicle,FlyingMixin): pass class Helicopter(Vehicle,FlyingMixin): pass
- Mixin in python is implemented through multiple inheritance
- Mixin must represent a function, not an object
- The function of Mixin must be single. If there are multiple functions, define several Mixin classes
- Mixin class is usually not used alone, but mixed with other classes to add functions
- Mixin class does not depend on the implementation of subclasses. Even if subclasses do not inherit mixin, they can operate normally, that is, some functions are missing
Benefits of using Mixin classes
1. The mixin mixed class design pattern extends the function of the class on the premise of modifying the content of the army class
2. Improve the reusability of the code and make the code structure simpler and clearer
3. The function can be adjusted arbitrarily according to the development needs
4. Avoid involving multi-level and complex inheritance relationships
19.6.3 abstract classes of design patterns (understand)
An abstract class is a special class:
1. Abstract classes cannot be used and cannot be directly instantiated as an object
2. Abstract classes contain abstract methods, which are methods that do not implement code
3. An abstract class can only be used if it needs subclass inheritance and overrides the abstract method of the parent class
Abstract classes are generally used in program design. In program design, functions and requirements are generally planned. Some requirements are clear and can be completed, but some may be unclear and uncertain about how to implement them
At this point, you can define the method that is uncertain how to implement or needs to be implemented later as an abstract method (only define the method name without writing specific code)
give an example:
The company has a new product that needs to be developed and handed over to the boss of the development department
boss began to design how to complete product development
It needs different technologies and different people to complete it
The boss has completed some functions, and some have defined requirements, but there is no specific implementation, which needs others
The completed part is Ordinary methods, unfinished ones can be understood as abstract methods
import abc # Defined as an abstract class, the metaclass attribute of this class must be metaclass=abc.ABCmeta class Writecode (metaclass=abc.ABCmeta): # You need abstract methods and decorators @abc.abstractmethod def write_php(self): pass def write_java(self): print('finished java') def write_python(self): print('completed python') # After definition, abstract classes cannot instantiate objects directly # ob = Writecode() # TypeError: # Define subclasses, inherit abstract classes, and implement abstract methods in abstract classes class Demo(Writecode): def write_php(self): print('achieve php') a = Demo() print(a)