Object-oriented programming

The idea of Object Oriented Programming (OOP) Programming is mainly designed for large-scale software. Object-oriented programming makes programs more extensible and readable.

Object-oriented programming encapsulates data and methods related to manipulating data into objects, and the way of organizing code and data is closer to people’s thinking, which greatly improves efficiency.

Python adopts the idea of faceted shared objects and fully supports basic object-oriented functions such as inheritance, abortion, encapsulation, and so on

Python supports procedural, object-oriented, functional programming, and more

The difference between object-oriented and procedural

Procedure-oriented thinking:

Process-oriented programming focuses more on the “logical flow of a program,” which is an executor mentality and is suitable for writing small programs.

Process oriented thinking, when thinking about a problem, first think about “how to achieve steps?” And do it step by step. How do you drive a car? Process oriented is good for simple, non-collaborative transactions.

Object Oriented thinking:

For the phenomenon of more attention is “the relationship between objects in software”, with a “designer” thinking, suitable for writing large-scale programs.

Object oriented thought is more suitable for people’s thinking mode.

Conclusion:

  • It’s the way you think about problems, the way you organize your code
  • You can use procedural orientation to solve simple problems
  • Solving complex problems: macroscopic using object-oriented grasp, microscopic processing is still process oriented

The definition of a class

Through the attributes (data) and methods (behavior) of the class Empire data type, that is, “classes bundle behavior and state together.”

An object is a concrete entity of a class, commonly referred to as an instance of a class. Class is regarded as “cookie handle”, and objects are made from this handle

When objects are created from a class, each object shares the behavior of the class (methods defined in the class), but has its own property values (no shared state). “Method code is shared, property data is not shared.”

In Python, everything is an object. Classes are also called class objects, and instances of classes are called “instance objects”

Syntax format:

Class Class name: class bodyCopy the code

Matters needing attention:

  1. Class names must comply with the “Identifier Rule”; Use the “hump rule” for multiple words
  2. We can define properties and methods in the class body
  3. Properties are used to describe data, and methods (or functions) are used to describe operations related to those data.

[Operation] test

class Student:
    # Attribute definition in constructor: __init__
    def __init__(self,name,score) :
        self.name = name
        self.score = score

    def say_score(self) :
        print(id(self))  # 2008779276616
        print(self.name,"The score is:",self.score)
s1 = Student("Zhang".93)
print(id(s1))  # 2008779276616
s1.say_score()
Copy the code

Classes are abstract templates

The constructor__init__

Classes are abstract, also known as “templates for objects.” We need to use the class template to create an instance object of the class, and then use the functionality defined by the class.

Three parts of a Python object:

  • Identity (Id) Indicates the Id
  • Type (object type)
  • Value (Object value)

Further statement:

  1. Identity (Id) Indicates the Id
  2. Type (object type)
  3. Value (Object value)
    1. Attributes
    2. Method

To create an object, we need to define the __init__() constructor method. The constructor is used to perform “initialization of the instance object”, that is, after the object is created, the relevant properties of the current object are initialized, and no value is returned.

__init__ () key points:

  1. The name is fixed and must be__init__()
  2. The first argument is fixed and must be self, which refers to the instance object being created
  3. Constructors are typically used to initialize instance properties of objects
  4. The class name (argument list) is used to call the constructor. When called, the window machine is returned to the appropriate variable
  5. __init__()Method: Initializes the created object. Initializing means assigning values to instance properties
  6. __new__()Method: Used to create an object, but the method is generally redefined without order.

Note:

  • Self in Python is the equivalent of the self pointer in C++, and the this keyword (referring to the scope of the current object) in Java and C#. In Python, self must be the first parameter to construct an argument. The name can be changed arbitrarily, but it is generally called self.

Instance attributes

Instance properties are properties that are subordinate to the instance object and are also called “instance variables.” Key points:

  1. Instance attributes are generally in__init__(self)Method is defined by the following code
    • Slef. instance attribute name = initial value
  2. Other instance methods of this class can also be accessed through self:
    • Self. instance attribute name
  3. After creating an instance object, access it through the instance object:
    • Obj01 = class name (xx, XXX, XXX__init__()Initialize properties
    • Obj01. Instance attribute name = value # You can assign values to existing attributes or add new ones

Instance methods

Instance methods are methods that are subordinate to instance objects. Define the format as follows:

Def method name (self [, parameter list]) : function bodyCopy the code

The method call format is as follows:

Object. Method name ([argument list])Copy the code

Note:

  • When defining an instance method, the first argument must be self. Self refers to the current instance object
  • Calling the instance method does not need to and cannot pass a value to self, which is passed automatically by the interpreter

The difference between functions and methods:

  1. Both are blocks of statements used to complete a function, essentially the same.
  2. When a method is called, it is called through an object. Methods are subordinate to specific instance objects, which normal functions do not.
  3. Intuitively, a method definition requires passing self; a function does not

Method call nature of instance object:

Other operations:

  1. Dir (obj) retrieves all properties and methods of an object
  2. The attributes of the obj.__dict__ object are self-built
  3. Pass null statement
  4. Isinstance (object, type) Determines whether object is a definite type

Class object

When the interpreter executes the class statement, it creates a class object.

[Operation] test

class Person:
    pass

print(type(Person))  # 
      
        type
      
print(id(Person))  # 1599475085048

stu01 = Person()
# s1 = stu01
print(stu01)  # <__main__.Person object at 0x000002B454EC9E08>
Copy the code

Pass is a placeholder

Class attribute

Class attributes are attributes that belong to “class objects” and also become “class variables”. Because class attributes are subordinate to class objects, they can be used by all instance objects.

Definition method:

Class Class name: Class name variable = initial valueCopy the code

In or out of a class, by: class name. Class name variable used.

[Operation] test

class Person:

    # class attribute
    school = Sino-canada Fung Wah International School
    tuition = 100000
    count = 0

    # instance attributes
    def __init__(self,name,age,gender) :
        self.name = name
        self.age = age
        self.gender = gender
        Person.count = Person.count+1

    # instance method
    def get_score(self) :
        print("Name: {0}; Age: {1}; Gender: {2}".format(self.name,self.age,self.gender))

stu1 = Person("sue".22."male")
stu2 = Person("Jason".22."male")
stu3 = Person("Allen".22."female")
stu1.get_score()
stu2.get_score()
stu3.get_score()
print("School: {0}; Tuition: {1}".format(Person.school,Person.tuition))
print("{0} instances created".format(Person.count))
Copy the code

Class method

A class method is a method that belongs to a class object. Class methods are defined by the @classMethod decorator in the format:

@classmethod def classmethod name (CLS [, parameter list]) : function bodyCopy the code

Note:

  • @classmethodMust be above the method
  • The first CLS must have: CLS stands for “class object” itself
  • Call class method format: “Class name. Class method name (argument list) “. The parameter list does not need or can not pass CLS values.
  • Accessing instance properties and instance methods in a class method causes an error
  • When a subclass inherits a superclass method, the CLS is passed as a subclass object, not a superclass object

【 Operation 】 test:

class Person:

    # class attribute
    school = Sino-canada Fung Wah International School
    tuition = 100000
    count = 0

    # instance attributes
    def __init__(self,name,age,gender) :
        self.name = name
        self.age = age
        self.gender = gender
        Person.count = Person.count+1

    @classmethod
    def printSchool(cls) :
        print(cls)
        print(cls.school)

    # instance method
    def get_score(self) :
        print("Name: {0}; Age: {1}; Gender: {2}".format(self.name,self.age,self.gender))

stu1 = Person("sue".22."male")
stu1.get_score()
Person.printSchool()
Copy the code

Class methods operate on class properties, and instance methods operate on instance properties

A static method

Python allows you to define methods independent of “class objects”, called “static methods”.

A static method is no different from a normal function defined in a module, except that the “static method” is placed in the “namespace of the class” and requires a “class call”.

Static methods are defined by the @staticMethod decorator, of the following format:

@staticmethod def staticmethod name ([parameter list]) : function bodyCopy the code

Note:

  1. @staticmethodIt must be written above the method
  2. Call format: “Class name. Static method name (parameter list)”
  3. Accessing instance properties and instance methods in static methods causes errors

[Operation] test

class Person:

    # class attribute
    school = Sino-canada Fung Wah International School
    tuition = 100000
    count = 0

    # instance attributes
    def __init__(self,name,age) :
        self.name = name
        self.age = age
        Person.count = Person.count+1

    # static instance
    @staticmethod
    def addNum(a,b) :
      print("{0} + {1} = {2}".format(a,b,a+b))
      return a+b

    # instance method
    def get_score(self) :
        print("Name: {0}; Age: {1}".format(self.name,self.age))

stu1 = Person("sue".22)
stu1.get_score()
Person.addNum(1.2)
Copy the code

__del__Method (analysis function) and garbage collection mechanism

The __del__ methods are called “destructor methods” and are used to implement the operations required when an object is destroyed. Ex: Releases resources occupied by objects, open file resources, and network connections.

Python implements automatic garbage collection, with the garbage collector calling the __del__ method when the object is not referenced (the reference count is 0).

By using the DEL statement to delete an object, the __del__ method is guaranteed to be provided automatically by the system. Custom destructor methods are generally not required

[Operation] test

class Person:

    def __del__(self) :
        print("Destroy object: {0}".format(self))

p1 = Person()  Person object at 0x000001DFCD279FC8>
print(id(p1))  # 1. 2060731260872
p2 = Person()  <__main__.Person object at 0x000001DFCD284088>
print(id(p2))  # 2. 2060731302024
del p2
print("over")  # 4. over
# print(id(p2)) # name 'p2' is not defined
Copy the code

__call__Methods and callable objects

An object that defines a __call__ method is called a “callable object”, that is, it can be called like a function.

The function of this method is similar to overloading the () operator in a class so that the class instance object can be used as an “object name ()” like a normal function call.

[Operation] test

class Get_Salary:

    def __call__(self, salary) :
        yearSalary = salary*12
        daySalary = salary//22.5
        hourSalary = daySalary//12

        return dictP1 = Get_Salary() p1 = Get_Salary()print(p1(8000)) You don't need to add a class name to use it
Copy the code

Method overloading

In other languages, it is possible to define multiple methods with the same name, as long as the method signature is unique. The method label name consists of three parts: method name, parameter number, and parameter type

In Python, the arguments to a method have no declared type (the type of argument is delimited when called), and the number of arguments can be controlled by mutable arguments. Therefore, there is no method overloading in Python. Defining a method can be called in multiple ways, which is equivalent to implementing method overloading in other languages.

If more than one method with the same name is defined in a class, only the last one takes effect.

[Operation] test

class Person:
    def say_Hi(self) :
        print("Hello")

    def say_Hi(self,name) :
        print("Hello,{0}".format(name))

p1 = Person()
p1.say_Hi("Js")  # say_Hi() missing 1 required positional argument: 'name'
Copy the code

Method dynamics

Python is a dynamic language, and we can dynamically add new methods to a class, or dynamically modify existing methods of a class.

[Operation] test

class Person:
    def hello_world(self) :
        print("Hello World")

def say_Hi(name) :
    print("Hello,{0}".format(name))

p1 = Person()
# p1.say_Hi("Js") # 'Person' object has no attribute 'say_Hi'

Person.say = say_Hi
# p1.say("!23")  # say_Hi() takes 1 positional argument but 2 were given
Person.say("he")
Copy the code

Private properties and private methods

Unlike other object-oriented approaches, Python does not have strict access control restrictions on members of a class. Note:

  1. By convention, properties that begin with two underscores are private. The others are public.
  2. Private properties (methods) can be accessed inside a class
  3. Private properties (methods) cannot be accessed directly from outside the class
  4. Private property methods can be accessed outside the class by _ class name __ Private property (method) name

[Note:] Methods are also properties in nature, but are simply executed by ().

Action Tests private properties and methods

class Employee:

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

    def  __work(self) :
        print("Good Good Work, Day Day Up")


p1 = Employee("Allen".12)
print(p1.name)  # Allen
# print(p1.age) # 'Employee' object has no attribute 'age'
print(p1._Employee__age)  # 12
# p1.__work() # 'Employee' object has no attribute '__work'
p1._Employee__work()  # Good Good Work, Day Day Up
Copy the code

@ the property a decorator

@property can change the way a method is called to a “property call.”

[Operation] Basic use

class Employee:

    @property
    def money(self) :
        print("working...")
        return 20000


p1 = Employee()  # 1. working...
# p1.money() # 'int' object is not callable
getMoney = p1.money
print(getMoney)  # 2. 20000
print(p1.money)  # 3. working... 4. 20000
Copy the code

_get and _set

【 Action 】 Set private attributes and modify salary

class Employee:

    def __init__(self,name,salary) :
        self.__name = name
        self.__salary = salary

    def get_salary(self) :
        # print(" salary: {0}". Format (self.__salary))
        return self.__salary

    def set_salary(self,salary) :
        if 10000<salary<50000:
            self.__salary = salary
            print("Payroll entry successful")
        else:
            print("Payroll entry failure")

p1 = Employee("Eason".30000)
print({0} Salary: {1}".format(p1._Employee__name, p1.get_salary()))  # Eason Salary: 30,000
# p1.set_salary(3000
p1.set_salary(20000)  # Salary entry successfully
print({0} Salary: {1}".format(p1._Employee__name, p1.get_salary()))  # Eason Salary: 20,000
Copy the code

But you can also modify private properties outside of a class using @Property

[Operation] test

class Employee:

    def __init__(self,name,salary) :
        self.__name = name
        self.__salary = salary

    @property
    def salary(self) :
        # print(" salary: {0}". Format (self.__salary))
        return self.__salary

    @salary.setter
    def salary(self,salary) :
        if 10000<salary<50000:
            self.__salary = salary
            print("Payroll entry successful")
        else:
            print("Payroll entry failure")

p1 = Employee("Eason".30000)
print({0} Salary: {1}".format(p1._Employee__name, p1._Employee__salary))  # Eason Salary: 30,000
p1.salary = -2000  Failed to enter salary
p1.salary = 20000  # Salary entry successfully
print({0} Salary: {1}".format(p1._Employee__name, p1._Employee__salary))  # Eason Salary: 20,000
Copy the code

Three characteristics of object orientation

Object-oriented programming is characterized by inheritance, encapsulation (hiding), and polymorphism

  • Encapsulate (hide) : Hides the properties and implementation details of an object to provide the necessary methods externally. Encapsulation is achieved by using “private properties, private methods”.
  • Inheritance inheritance can make the subclass have the characteristics of the parent class, and improve the code reuse rate. In terms of design, it is an incremental evolution. If the original design of the parent class remains unchanged, new functions can be added or improved
  • Polymorphism refers to the fact that the same method call behaves differently depending on the object.

Inheritance (emphasis)

Inheritance is an important feature of object-oriented programming and a means of code reuse

If a new class inherits from a designed class, it directly inherits the characteristics of an existing class, making the job much easier. Call it a parent or base class, and the new class is called a subclass or derived class

Python supports multiple inheritance. A subclass can inherit from more than one parent class.

Class The name of the subclass (parent 1[, parent 2... ) : the class bodyCopy the code

If no parent is specified in the class definition, the default parent is the Object class.

Object is the parent class of all classes, which defines some default implementations common to all classes.

When you define a subclass, you must call the parent class’s constructor in its constructor. Format:

Parent class name.__init__(self, argument list) :Copy the code

[Operation] test

class Person:

    def __init__(self,name,age) :
        self.name = name
        self.__age = age  # private attributes

    def say_hi(self) :
        print("Hello,Bro!!!")

class Children(Person) :

    Subclasses inherit attributes from their parent class
    def __init__(self,name,age,score) :
        Person.__init__(self,name,age)
        self.score = score


print(
    Children.mro()
)  # [<class '__main__.Children'>, <class '__main__.Person'>, <class 'object'>]
c1 = Children("Jason".23.100)
c1.say_hi()  # Hello,Bro!!! Inherits the attribute methods of the parent class

# Access private attributes
Private attributes that are accessed by subclasses of the parent class
print(c1._Person__age)  # 23
print(dir(c1)) #... Various implementations
Copy the code

Method rewriting

  1. Member inheritance: A subclass inherits all the members of its parent class except the constructor.
  2. Method override: A subclass may redefine a method of its parent class so that it overrides the method of its parent class. Also known as “override”

[Operation] Rewrite the test

class Person:

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

    def say_hi(self) :
        print("Hello,Bro!!!")
class Children(Person) :

    Subclasses inherit attributes from their parent class
    def __init__(self,name,age,score) :
        Person.__init__(self,name,age)
        self.score = score

    def say_hi(self) :
        print("What's Up?")

s1 = Children("Sue".21.100)
s1.say_hi()  # What's Up?
Copy the code

The object root class

The Object class is the parent of all classes, so all classes have object properties and methods.

View all properties of the object through dir()

print(dir(Person))
Copy the code

Results:

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'say_hi']
Copy the code

View the inheritance structure with MRO ()

print(Children.mro())
Copy the code

Results:

[<class '__main__.Children'>, <class '__main__.Person'>, <class 'object'>]
Copy the code

Key points:

  1. Dir () viewing properties shows all properties including our own defined methods
  2. “Say_hi” is a method, but it’s also an attribute.

Multiple inheritance

Python supports multiple inheritance, where a subclass can have more than one “direct parent” class. This gives you the characteristic of multiple parent classes. However, the overall level of class complexity can be avoided

[Operation] Test multiple parent classes

class A:
    def aa(self) :
        print("----AA----")


class B:
    def bb(self) :
        print("----BB----")


class C(A, B) :
    def cc(self) :
        print("----CC----")


p1 = C()    
Copy the code

Mro () function

Python supports multiple inheritance, and if there is a method of the same name in a parent class, the interpreter searches it “left to right” if the child class does not specify a parent class name

Method Resolution Order (MRO) : Method Resolution Order. The mrO () method is used to get the “hierarchy of classes” and also to look up the hierarchy of this class.

class A:
    def aa(self) :
        print("----AA----")

    def say(self) :
        print("Hello AAA")


class B:
    def bb(self) :
        print("----BB----")

    def say(self) :
        print("Hello BBB")


Class A say will be executed from left to right.
class C(A, B) :
    def cc(self) :
        print("----CC----")


p1 = C()
p1.cc()
p1.say()
Copy the code

The hierarchy of classes output by the MRo () function

print(
    C.mro()
)  # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
Copy the code

The Super() function gets the superclass definition

In a subclass, when you get a method of the parent class, you can call super() super() to represent the definition of the parent class, not the superclass object

class A:
    def aa(self) :
        print(self)

class B(A) :
    def bb(self) :
        # Method 1: Direct access
        A.aa(self)  # <__main__.B object at 0x000001D4638F9F88>
        # method 2: super() fetch
        super().aa()  # <__main__.B object at 0x000001D4638F9F88>
        print(self)  # <__main__.B object at 0x000001D4638F9F88>

b = B()
b.bb()
Copy the code

Polymorphism (emphasis)

A Polymorphism is the ability of the same method call to behave differently depending on the object.

Key points:

  1. When a method is polymorphic, properties are not polymorphic
  2. There are two necessary conditions for polymorphism to exist: inheritance and method rewriting

[Operation] Test method polymorphism

class Person:
    def say(self) :
        print("Talk to me. You.")

class Chinese(Person) :
    def say(self) :
        print("Chinese...")

class Japanese(Person) :
    def say(self) :
        print("Japanese...")

class Amercian(Person) :
    def say(self) :
        print("English...")

def people(x) :
    if isinstance(x, Person):
        x.say()
    else:
        print("Please speak in English.")

people(Chinese())
people(Japanese())
people(Amercian())
Copy the code

The isinstance() function checks whether an object is of a known type

Sinstance () differs from type() :

  • Type () does not consider a subclass to be a parent type, regardless of inheritance.
  • Isinstance () considers a subclass to be a superclass type, considering inheritance.

Isinstance () is recommended to determine whether two types are the same.

Special methods

Common special methods:

Each operator is also a corresponding method:

Special attributes

Python objects contain many properties that start and end with double underscores, and these are special properties that have special uses.

Design patterns

Design patterns are unique to object-oriented languages. They are fixed practices when we are faced with a certain kind of problem. There are many kinds of design patterns.

There are two common patterns:

  • The factory pattern
  • A single mode

The factory pattern realizes the separation of creator and caller, and uses a special factory class to select the first implementation class and create objects for unified management