Advanced Python -- object oriented programming ③

Posted by anybody99 on Wed, 26 Jan 2022 18:21:49 +0100

Private properties and private methods

01. Application scenario and definition method

Application scenario

  • In actual development, some properties or methods of an object may only be used inside the object rather than being accessed outside
  • Private properties are properties that an object does not want to expose
  • A private method is a method that an object does not want to expose

Definition method

  • When defining an attribute or method, add two underscores before the attribute or method name to define a private attribute or method

class Women:

    def __init__(self, name):

        self.name = name
        # Don't ask the girl's age
        self.__age = 18

    def __secret(self):
        print("My age is %d" % self.__age)


xiaofang = Women("Xiao Fang")
# Private property, which cannot be accessed directly from outside
# print(xiaofang.__age)

# Private method, which cannot be called directly from outside
# xiaofang.__secret()

02. Pseudo private attributes and private methods

Tip: in daily development, do not use this method to access private properties or private methods of objects

In Python, there is no real private

  • When naming attributes and methods, some special processing is actually done to the name, which makes it inaccessible to the outside world
  • Processing method: add before the name_ Class name = >_ Class name__ name
# Private property, which cannot be accessed directly from outside
print(xiaofang._Women__age)

# Private method, external method cannot be called directly
xiaofang._Women__secret()

Single case

01. Single case design mode

  • Design mode

    • Design patterns are the summary and refinement of previous work. Generally, the widely circulated design patterns are mature solutions to a specific problem
    • The purpose of using design patterns is to reuse code, make code easier to be understood by others and ensure code reliability
  • Single case design mode

    • Purpose - let the object created by the class have only one instance in the system
    • The memory address of the object returned by the class name () is the same every time

Application scenario of single case design pattern

  • Music playback object
  • Recycle bin object
  • Printer object
  • ......

02. __new__ method

  • When creating an object using the class name (), the Python interpreter first calls__ new__ Method to allocate space for the object
  • __ new__ It is a built-in static method provided by the object base class. It has two main functions:
      1. Allocate space for objects in memory
      1. Returns a reference to an object
  • After the Python interpreter obtains the reference of the object, it passes the reference as the first parameter to the__ init__ method

Rewrite__ new__ Method code is very fixed!

  • Rewrite__ new__ Method must return super()__ new__ (cls)
  • Otherwise, the Python interpreter will not call the initialization method of the object if it cannot get the object reference with allocated space
  • Note:__ new__ Is a static method, which needs to actively pass cls parameters when calling

Sample code

class MusicPlayer(object):

    def __new__(cls, *args, **kwargs):
        # If no results are returned,
        return super().__new__(cls)

    def __init__(self):
        print("Initialize music playback object")

player = MusicPlayer()

print(player)

03. Singleton in Python

  • Singleton - an object created by a class that has only one instance in the system
    1. Define a class attribute with an initial value of None, which is used to record the reference of the singleton object
    2. Rewrite__ new__ method
    3. If the class attribute is None, call the parent class method to allocate space and record the result in the class attribute
    4. Returns the object reference recorded in the class property

class MusicPlayer(object):

    # Define class attribute record singleton object reference
    instance = None

    def __new__(cls, *args, **kwargs):

        # 1. Judge whether the class attribute has been assigned
        if cls.instance is None:
            cls.instance = super().__new__(cls)

        # 2. Return singleton reference of class attribute
        return cls.instance

Perform initialization only once

  • Each time an object is created using the class name (), the Python interpreter automatically calls two methods:
    • __ new__ Allocate space
    • __ init__ Object initialization
  • In the previous section__ new__ After the method transformation, you will get the reference of the object created for the first time every time
  • However: the initialization method will be called again

demand

  • Let the initialization action be executed only once

terms of settlement

  1. Define a class attribute init_flag flag indicates whether initialization has been performed. The initial value is False
  2. In__ init__ Method, determine init_flag. If it is False, the initialization action will be executed
  3. Then set init_flag set to True
  4. In this way, it is called automatically again__ init__ Method, the initialization action will not be executed again
class MusicPlayer(object):

    # Record the reference of the first created object
    instance = None
    # Record whether initialization action has been performed
    init_flag = False

    def __new__(cls, *args, **kwargs):

        # 1. Judge whether the class attribute is an empty object
        if cls.instance is None:
            # 2. Call the method of the parent class to allocate space for the first object
            cls.instance = super().__new__(cls)

        # 3. Return the object reference saved by the class attribute
        return cls.instance

    def __init__(self):

        if not MusicPlayer.init_flag:
            print("Initialize music player")

            MusicPlayer.init_flag = True


# Create multiple objects
player1 = MusicPlayer()
print(player1)

player2 = MusicPlayer()
print(player2)

polymorphic

Three characteristics of object oriented

  1. Encapsulation encapsulates attributes and methods into an abstract class according to their responsibilities
    • Guidelines for defining classes
  2. Inheritance realizes the reuse of code, and the same code does not need to be written repeatedly
    • Design skills
    • Subclasses write specific code for their specific needs
  3. Polymorphic different subclass objects call the same parent method to produce different execution results
    • Polymorphism can increase the flexibility of code
    • On the premise of inheriting and overriding parent class methods
    • It is the skill of calling methods and will not affect the internal design of classes

Polymorphic case drill

demand

  1. Encapsulate the method game in the Dog class
    • Ordinary dogs are simply playing
  2. XiaoTianDog is defined to inherit from Dog and override the game method
    • Howling dogs need to play in the sky
  3. Define the Person class and encapsulate a method to play with the dog
    • Inside the method, directly let the dog object call the game method

Case summary

  • In the Person class, you only need to let the dog object call the game method, and you don't care what the dog is
    • The game method is defined in the Dog parent class
  • When the program is executed, different dog object arguments are passed in, which will produce different execution effects

Polymorphism makes it easier to write general code and make general programming to adapt to the changing needs!

class Dog(object):

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

    def game(self):
        print("%s Bouncing play..." % self.name)


class XiaoTianDog(Dog):

    def game(self):
        print("%s Fly to the sky to play..." % self.name)


class Person(object):

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

    def game_with_dog(self, dog):

        print("%s and %s Happy play..." % (self.name, dog.name))

        # Let the dog play
        dog.game()


# 1. Create a dog object
# wangcai = Dog("Wangcai")
wangcai = XiaoTianDog("Feitian Wangcai")

# 2. Create a Xiaoming object
xiaoming = Person("Xiao Ming")

# 3. Let Xiao Ming call the method of playing with the dog
xiaoming.game_with_dog(wangcai)
        

Topics: Python Back-end