Python Note -- Day 14. Object oriented - Advanced

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)

Tags: Python

Posted on Sat, 16 Oct 2021 02:24:25 -0400 by 051119