Python learning notes class encapsulation & class inheritance & polymorphic inheritance & class methods and static methods & singleton design pattern

1, Class encapsulation:

1. Concept:

Generalized encapsulation: the definition of functions and classes is the embodiment of encapsulation

Encapsulation in a narrow sense: some attributes of a class do not want to be directly accessed by the outside world in the process of use. Instead, this attribute is private [only held by the current class], and then exposed to the outside world. An access method can be called [indirect access attribute]

The essence of encapsulation: it is the process of attribute privatization

Advantages of encapsulation: it improves the security and reusability of data

2. Privatization of attributes and methods:

If you want the member variable not to be directly accessed by the outside world, you can add two underscores _ in front of the attribute name, Member variables are called private member variables

Characteristics of private attributes: they can only be accessed directly inside the class, but not outside

# class
class Person:
    def __init__(self, name, age, sex):
        self.name = name  # Public attribute
        self.__age = age  # Private attribute: an attribute starting with a double underscore. It can only be used inside the current class
        self._sex = sex  # Public attribute, but this is not recommended

    def run(self):
        print(self.__age)
        self.__eat()
        
    # Private method
    def __eat(self):
        print("eat")


# object
p = Person('Lu Han', 30, 'male')
print(p.name)
# print(p.__age)  # Error reporting__ age is a private property
print(p._sex)
p.run()
print()

# p.__eat()  # Error reporting__ eat() is a private method

'' in class__ Attribute name/__ 'method name 'indicates that the property / method is a private property / method. Subclasses cannot inherit and cannot be called externally.

Private class in the above program__ sex and private methods__ eat() cannot be called, but it can be called by other means, but I don't mind using it like this.

You can call private properties or private methods in the following ways,But don't do that
print(p._Person__age)
p._Person__eat()

3.get function and set function

get function and set function are not system functions, but user-defined. In order to coincide with the concept of encapsulation, they are named getXxx and setXxx

Get function: get value

set function: assignment [transfer value]

Because the private property / method of a class cannot be inherited and called, we introduce get function and set function to obtain and modify the private property / method.

class Person2():
 def __init__(self,name,age):
     self.name = name
     self.__age = age
     #Special case I
     self.__weight__ = 20.0
     #Special case II
     self._height = 155.0

 def myPrint(self):
     print(self.name,self.__age)
p2 = Person2("abc",10)
p2.myPrint()   #abc 10

3.1 get function:

#Get function: get the value of member variable
 #Naming method: getXxx
 #Features: you need to set the return value to return the value of the member variable
 def getAge(self):
     return self.__age
 print(p2.getAge()) #  10

3.2 set function:

 #set function: assign value to member variable
 #Naming method: setXxx
 #Features: parameters need to be set, which are related to private member variables
 def setAge(self,age):
     #Data filtering
     if age < 0:
         age = 0
     self.__age = age
p2.setAge(22)
print(p2.getAge()) # 22

Summary: by privatizing attributes and providing get and set functions, external code can not change the value of member variables at will, which ensures the security of data to a certain extent

4.@property decorator

Function of decorator: it can dynamically add functions to functions. For member methods of classes, decorators also work

The function of Python's built-in @ property decorator: turn a function into a property

@property decorator: simplify get and set functions

Use: @ property decorator is equivalent to get function. At the same time, a new decorator @ property name will be generated Setter, which is equivalent to the function of set

Function: used in the member function in the class, it can simplify the code and ensure the verification of parameters

class Person1():
 def __init__(self,name,age):
     self.__name = name
     self.__age = age

 def myPrint(self):
     print(self.__name,self.__age)
  @property
 def age(self):
     return  self.__age

 #Note: the naming method of the function should be consistent with that in @ property
 #Function: equivalent to set function, set parameters and assign values to member variables
 @age.setter
 def age(self,age):
     if age < 0:
         age = 0
     self.__age = age

 @property
 def name(self):
     return  self.__name

 @name.setter
 def name(self,name):
     self.__name = name


p1 = Person1("abc",10)
p1.myPrint()   #abc 10
#p1.setAge(20)
#print(p1.getAge())

print(p1.age)  #10
p1.age = 18   #It is equivalent to calling the set function and transferring 18 values. In essence, it calls @ age Setter modified function
print(p1.age) #It is equivalent to calling the get function to get the value of the member variable. In essence, it calls the function decorated with @ people

p1.name = "zhangsan"
print(p1.name)

5. Private method

If you add _ before a function name in the class, It is considered that this member function is privatized

Features: it can not be called directly from the outside, but only from within the class

class Site():
 def __init__(self,name):
     self.name = name

 def who(self):
     print(self.name)
     self.__foo()

 #Private member methods can only be called inside the current class
 def __foo(self):    #Private function
     print("foo")

 def foo(self):    #Public function
     print("foo~~~~")

 #Note: the above two functions are two different functions, and there is no coverage problem

s = Site("shenshi")
s.who()
#s.__foo()  #AttributeError: 'Site' object has no attribute 'foo'
s.foo()

2, Class inheritance:

1. Concept:

If two or more classes have the same properties or member methods, we can extract a class and declare the common part in the extracted class

​ Extracted classes: parent class, base class, superclass, root class

​ Two or more classes: subclasses, derived classes

​ The relationship between them: the subclass inherits from the parent class

be careful:

​ a.object is the parent class of all classes. If a class does not explicitly indicate its parent class, it defaults to object

​ b. Simplify the code and improve the reusability of the code

2. Single inheritance:

2.1 use:

Simply put, a subclass can only have one parent, which is called singleton inheritance

Syntax:

Parent class:

Class parent class name (object):

​ Class body [part common to all subclasses]

Subclass:

Class subclass class name (parent class name):

​ Class body [subclass specific attributes and member methods]

If there is no explicit description of the parent class, object will be written as a general class

person.py file [parent]

#1. Define parent class
class Person(object):
 #Constructor [member variable]
 def __init__(self,name,age):
     self.name = name
     self.age = age


 #Member method
 def show(self):
     print("show")

 def __fun(self):
     print("fun")

worker.py file [subclass 1]

from  extends01.person import Person

#2. Define subclasses
class Worker(Person):
 #Constructor [member variable]
 def __init__(self,name,age,job):
     """
     self.name = name
     self.age = age
     """
     self.job = job

     #6. call the constructor of the parent class in the constructor of the child class [inherit the member variable of the parent class from the parent class]
     #Method 1: Super (current subclass, self)__ init__ (attribute list)
     #super(Worker, self).__init__(name,age)
     #Method 2: parent class name__ init__(self, attribute list)
     Person.__init__(self,name,age)
     #Method 3: Super ()__ init__ (attribute list)
     #super().__init__(name,age)


 #Member method
 def work(self):
     print("work")

student.py file [subclass 2]

from extends01.person import  Person

class Student(Person):
 # Constructor [member variable]
 def __init__(self, name, age, score):

     Person.__init__(self,name,age)
     self.score = score

 # Member method
 def study(self):
     print("study")

extendsDemo01.py file [ test module ]

#Test module
from extends01.person import Person
from extends01.worker import Worker
from extends01.student import Student

#3. Create the object of the parent class
p = Person("zhangsan",10)
p.show()
#p.__fun()

#4. Create subclass objects
w = Worker("aaa",20,"worker")
w.work()

#5. The subclass object accesses the content in the parent class
#Conclusion 1: subclass objects can call public member methods in the parent class (except private methods because of inheritance)
w.show()
#w.__fun()
#Conclusion 2: by calling the constructor of the parent class in the constructor of the subclass, the subclass object can directly access the member variables in the parent class (except private variables)
print(w.name,w.age,w.job)

s = Student("Xiao Ming",9,90)
s.study()
s.show()

2.2 special usage:

If a member function with the same name as the parent class appears in the subclass, the member function in the subclass will be called first

s = Student("Xiao Ming",9,90)
s.study()
s.show()

Can the parent class object access the unique member functions and member variables in the child class? ------ > No

per = Person("gs",10)
#per.work()

Can the slots attribute be applied to subclasses
Conclusion 3: defining slots attribute in the parent class restricts the definition of attributes, which cannot be used in subclasses unless you add your own restrictions in subclasses

#Parent class
class Student(object):
 __slots__ = ("name","age")

#Subclass
class SeniorStudent(Student):
 pass


s  = Student()
s.name = "zhangsan"
s.age = 10
#s.score = 90

ss = SeniorStudent()
ss.name = "lisi"
ss.age = 20
ss.score = 60

2.3 summary:

Characteristics of inheritance:

​ a. Subclass objects can directly access non privatized properties in the parent class

​ b. Subclass objects can call non privatized member methods in the parent class

​ c. The parent class object cannot access or call any content in the child class

Advantages and disadvantages of inheritance:

advantage:

​ a. Simplify code and reduce code redundancy

​ b. Improve code reusability

​ c. It improves the maintainability of the code

​ d. Inheritance is the premise of polymorphism

Disadvantages:

​ Coupling is usually used to describe the relationship between classes. The lower the coupling, the higher the quality of the code

​ However, in the inheritance relationship, the coupling is relatively high (if the parent class is modified, the child class will also change with it)

3. Multiple inheritance:

A subclass can have more than one parent class

Syntax:

Class subclass class name (parent class 1, parent class 2, parent class 3.):

​ Class body

Code demonstration:

father.py file [parent class 1]

class Father(object):
 def __init__(self,money):
     self.money = money

 def play(self):
     print("playing")

 def fun(self):
     print("father Medium fun")

mother.py file [parent class 2]

class Mother(object):
 def __init__(self,faceValue):
     self.faceValue = faceValue

 def eat(self):
     print("eating")

 def fun(self):
     print("mother Medium fun")

child.py file [subclass]

from extends02.father import Father
from extends02.mother import Mother

#Define subclasses with multiple superclasses
class Child(Mother,Father):
 def __init__(self,money,faceValue,hobby):
     #Call the constructor in the parent class
     Father.__init__(self,money)
     Mother.__init__(self,faceValue)
     self.hobby = hobby

 def study(self):
     print("study")

extendsDemo03.py file [ test module ]

from extends02.father import Father
from extends02.mother import Mother
from extends02.child import Child


f = Father(100000)
m = Mother(3.0)

#Create subclass object
c = Child(1000,3.0,"Play games")
#Subclass objects call member methods in the parent class
c.play()
c.eat()

#Conclusion; If there is the same function in multiple parent classes, it is called through the object of the child class. Which function in the parent class is called depends on the order in which it appears in the parent class list
c.fun()

4. Function override:

If a function with the same name as the parent class appears in a subclass, it is considered to be an override of the function in the parent class

4.1 system function Rewriting:

_str_
_repr_

class Animal(object):
 def __init__(self,name,age):
     self.name = name
     self.age = age

 #Rewrite__ str__ Function. After rewriting, it generally return s a string about member variables
 def __str__(self):
     return "name=%s age=%d"%(self.name,self.age)

 #Rewrite__ repr__, The function is the same as that of str, and str is preferred
 def __repr__(self):
     return "name=%s age=%d"%(self.name,self.age)

a = Animal("chinese rhubarb",10)
print(a)   #<__main__.Animal object at 0x00000226A87AC240>
print(a.__str__())

#When a class inherits from object, the printed object obtains the address of the object, which is equivalent to calling the parent class through the subclass object__ str__
#Called by default when printing objects__ str__ function
#Rewrite__ str__ Function: to debug the program

Usage timing: when an object has many attributes and needs to be printed, it can be rewritten__ str__, It can simplify the code and debug the program

4.2 user defined function Rewriting:

#Timing of function Rewriting: in the inheritance relationship, if the function in the parent class cannot meet the needs of the child class, it needs to be rewritten in the child class
#Parent class
class People(object):
 def __init__(self,name):
     self.name = name

 def fun(self):
     print("fun")

#Subclass
class Student(People):
 def __init__(self,name,score):
     self.score = score
     super(Student,self).__init__(name)

 #rewrite; Rewrite the declaration and implementation of the function
 def fun(self):
     #Call the function in the parent class in the subclass function [1. want to use the function in the parent class, 2. need to add a new function]
     #Decide whether to call the function in the parent class according to the specific requirements
     super(Student,self).fun()
     print("fajfhak")


s = Student("fhafh",10)
s.fun()

3, Polymorphic inheritance:

The rewriting of a function is actually an embodiment of polymorphism

In Python, polymorphism refers to the reference of the parent class pointing to the object of the child class

#Parent class
class Animal(object):
	pass

#Subclass
class Dog(Animal):
	pass

class Cat(Animal):
	pass

#Define variables
a = []   #A is a list type
b = Animal()  #b is an Animal type
c = Cat()  #c is Cat type

#isinstance(): judge whether an object belongs to a certain type (system or user-defined type)
print(isinstance(a,list))
print(isinstance(b,Animal))
print(isinstance(c,Cat))

print(isinstance(c,Animal))  #True
print(isinstance(b,Dog))   #False

Conclusion: the subclass object can be the parent type, but the parent object cannot be the subclass type

4, Class methods and static methods:

1. Class method:

Class method: the method decorated with @ classmethod decorator is called class method. It can be called by class name or object, but it is usually called by class name

class Test(object):
#1. Class attribute
age = 100

def __init__(self,name):
  #2. Instance properties
  self.name = name

#3. Member method, called by object
#There must be a parameter, which is generally self, and self represents the current object
def func(self):
  print("func")

#4. Class method
"""
a.There must be a parameter, which is generally cls,cls Represents the current class
b.Class methods belong to the whole class, not to a specific object. They are prohibited in class methods self
c.Inside a class method, you can directly cls Call properties and methods in the current class
d.Inside a class method, you can cls create object
"""
@classmethod
def test(cls):
  print("Class method")
  print(cls)   #<class 'methodDemo01.Test'>
  print(cls.age)

  #6
  #Note: cls is used entirely as the current class
  c = cls("hello")
  c.func()

2. Static method:

Static method: the method decorated with @ staticmethod decorator is called static method. It can be called by class name or object, but it is usually called by class name

#1. Static method
@staticmethod
def show():
  print("Static method")

t = Test("hjfsh")
t.func()

#2. Call class method
Test.test()   #Class name Name of class method ()
t.test()       #Object Name of class method ()

#3. Call static method
Test.show()
t.show()

3. Summary:

Differences between instance method [member method], class method and static method

a. Grammatically

​ Instance method: the first parameter is generally self, which does not need to be passed when calling. It represents the current object instance

​ Static method: no special requirements

​ Class method: the first parameter must be cls, which represents the current class

b. On call

​ Instance method: only objects

​ Static method: object or class

​ Class method: object or class

c. [similarities] in inheritance

​ Instance method, static method, class method: when a function with the same name as that in the parent class appears in the subclass, the subclass object calls the method in the subclass [override]

class SuperClass(object):
@staticmethod
def show():
  print("Static method in parent class")

@classmethod
def check(cls):
  print("Class method in parent class")

class SubClass(SuperClass):
pass

s = SubClass()
s.show()
s.check()

Note: pay attention to distinguish the writing forms of the three functions. There is no absolute distinction in use

5, Common properties in class:

class Animal(object):
def __init__(self,arg):
  super(Animal, self).__init__()
  self.arg = arg


class Tiger(Animal):
age = 100
height = 200

def __init__(self,name):
  #super(Tiger, self).__init__(name)
  self.name = name

def haha(self):
  print("haha")

@classmethod
def test(cls):
  print("cls")

@staticmethod
def show():
  print("show")


if __name__ == "__main__":

1.__name__

__name__
Get the class name string through class name access
Cannot access through object, otherwise an error will be reported

#1.__name__
print(Tiger.__name__)  #Tiger

t = Tiger("")
#print(t.__name__)  #AttributeError: 'Tiger' object has no attribute '__name__'

__dict__
Access through the class name to obtain the information of the specified class [class method, static method, member method], and return a dictionary
Through object access, get the information of the object [all attributes and values], and return a dictionary

#2.__dict__
print(Tiger.__dict__)  #Class properties, all methods
print(t.__dict__)   #Instance properties

__bases__
Access through the class name to view all the parent classes of the specified class [base class]

#3.__bases__, Gets all the parent classes of the specified class and returns a tuple
print(Tiger.__bases__)

6, Single case design mode:

1. Concept:

What is a design pattern

​ The solution of the problem has been summarized

​ Among the 23 design modes, the more commonly used are single case design mode, factory design mode, agent mode and decoration mode

What is singleton design pattern

​ Single instance [object]

​ In the process of program running, ensure that a class can only have one instance [object]. No matter which module gets the object, the same object is obtained

​ The core of singleton design pattern: a class has and only has one instance, and this instance needs to be applied in the whole project

2. Application scenario:

Practical application: database connection pool operation ------ "many places in the application need to connect to the database ------" only one connection pool needs to be created to avoid the waste of resources

3. Realize:

3.1 module:

Python modules are natural singleton design patterns

Working principle of the module:

​ import xxx: when the module is imported for the first time, a pyc file will be loaded directly when it is imported for the second time pyc file, the module source code will no longer be executed

3.2 using new:

new(): the process of instance from scratch [object creation process]

class Singleton(object):
#Class properties
instance = None

#Class method
@classmethod
def __new__(cls, *args, **kwargs):
  #If the value of instance is not none, it indicates that it has been instantiated, and it will be returned directly; If none, it needs to be instantiated
  if not cls.instance:
      cls.instance = super().__new__(cls)

  return cls.instance

class MyClass(Singleton):
pass

#Automatically called when an object is created
one = MyClass()
two = MyClass()

print(id(one))
print(id(two))

print(one is two)

7, Exercise:

  1. Using the characteristics of encapsulation and inheritance, complete the following operations:

    pupil:
    Properties:
    full name
    Student number
    Age
    Gender
    Behavior:
    study
    fight

    middle school student:
    Properties:
    full name
    Student number
    Age
    Gender
    Behavior:
    study
    fall in love

    college student:
    Properties:
    full name
    Student number
    Age
    Gender
    Behavior:
    study
    Play games

  2. The owner, Mrs. Yang, introduced her pet dog and cat to the guest, Miss Li

    pet dog:
    Nickname: Beibei
    Age: 2
    Gender: Female
    The ability to walk on two legs

    Pet cat:
    Nickname: Huahua
    Age is 1
    Gender: Male
    A talent for pretending to be dead

  3. Students: name, age, student number, grade
    Class: class name, student list
    Show all students
    Find students by student number
    Add a student
    Delete a student (Student object, student number)
    Sort by student number in ascending order
    Sort in descending order according to grades

8, Answer to last exercise:

  1. Xiaomei walks Wangcai in Chaoyang Park [Note: Wangcai is a dog]
class Person:
    def __init__(self, name):
        self.name = name

    def play_dog(self, place):
        print(self.name, "stay", place, "Liuwangcai")


xiaomei = Person("Xiaomei")
xiaomei.play_dog("Chaoyang Park ")
  1. Li Xiao held a party at home and introduced his yellow pet dog [Caicai] to his friends. It has the special function of walking on two legs.
class Person2:
    def __init__(self, name, dog):
        self.name = name
        self.dog = dog

    def exception(self, excep):
        print(f'{self.name}Drive at home party,Introduce your family to your friends{self.dog.coloer}My pet dog{self.dog.name}have{excep}The specific function of.')


class Dog:
    def __init__(self, name, coloer):
        self.name = name
        self.coloer = coloer


dog = Dog('[[color]', 'yellow')
per = Person2('Li Xiao', dog)
per.exception('Walking on two feet')
  1. Wang Mei's Dutch pet pig [stupid] ran away. She cried and posted for pig enlightenment.
class Person3:
    def __init__(self, name):
        self.name = name

    def crry(self, findpig, pig):
        print(f'{self.name}Homely{pig.where}Pet pig{pig.name}Lost,She cried{findpig}')


class Pig(Person3):
    def __init__(self, name, where):
        self.name = name
        self.where = where


per3 = Person3('Wang Mei')
pig = Pig('[Stupid]', 'Netherlands')
per3.crry('Revelation of looking for pigs.', pig)
  1. Define a "Circle" class, the center of which is the "Point" class, construct a Circle, calculate the circumference and area of the Circle, and judge the relationship between a Point and the Circle
    Circle:
    Attributes: radius, center
    Method: perimeter, area
    Point:
    Attributes: x,y
# circular
class Circle:
    def __init__(self, r, p):
        self.r = r
        self.p = p

    def zhouchang(self):
        return 2 * self.r * 3.14

    def area(self):
        return self.r ** 2 * 3.14


# spot
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def relation_circle(self, circle):
        a = self.x - circle.p.x
        b = self.y - circle.p.y
        c = math.sqrt(a * a + b * b)

        if c > circle.r:
            print("Outside the circle")
        elif c < circle.r:
            print("In circle")
        else:
            print("On a circle")


# object
c = Circle(5, Point(3, 4))
p = Point(6, 8)

p.relation_circle(c)

Tags: Python Class OOP encapsulation

Posted by loveccb on Tue, 24 May 2022 14:40:03 +0300