Object oriented introduction
To understand surface objects, we must first understand the concept of objects. In the program, we simplify things into data (i.e. attributes and functions), the state of things is attributes, and the action is functions
Taking a cat as an example, the attributes of a cat may include variety, hair color, age, etc. These can be described as attributes, which can be expressed by variables. Actions such as eating, running, grasping, etc. can be expressed by functions. Integrating many attributes and functions related to the cat forms the cat object
Classes and objects
Above, we know what is the concept of object, but now there is a problem. For cats, there are many kinds, long haired, short haired, black, white, and even different names. If we create an object for each cat, it will become very troublesome when writing programs. Let's talk about the concept of class
What is a class? We classify all cats into one class. When we want to create an object, we directly enter the parameters of the object (called instantiation) in the class to create it, which simplifies the repeatability of the code and improves the efficiency
Obviously, when designing a program, there should be classes before objects
# Define class class BlackCat: # It is suggested to name the hump color='black' def jump(self): print('It jumped') blackcat1=BlackCat() # The instantiation process generates an object. The formation has a color attribute and a jump method # This class is created, but now the color of each cat in the case is black. What if you want some different attributes, such as name and age class BlackCat: # It is suggested to name the hump color='black' def __init__(self,name,age): self.name=name self.age=age def jump(self): print('%s Jumped'%self.name) blackcat2=BlackCat('Xiaobai',2) # init method is an initialization operation. It can pass in the instantiated object itself and the parameters passed in during instantiation for initialization, so that you can use multiple different objects blackcat3=BlackCat('Xiao Hei',1) # Classes are different from functions. Functions are not executed when they are defined. They are executed only when parentheses are added. However, classes are loaded when they are defined. In python__ dict__ Method can view the contents of definitions in a class print(BlackCat.__dict__) # Returns a dictionary containing key value pairs consisting of attributes and attribute values, functions, and function objects print(BlackCat.__dict__['color']) # Of course, it can also be taken in this way # Meaning of self ''' self It's not fixed, that is, it's just a variable name, like args Like, it's a conventional name self The meaning of is the created object itself, blackcat3=BlackCat('Xiao Hei',1) When you create an object, self It means blackcat3,init The object itself is passed in for initialization to get an object '''
Attribute lookup
When instantiating an object, it will first create an object namespace and store the unique attributes of the object (that is, the attributes created during initialization) in it. For the common attributes of the object, they will be stored in the class namespace. When searching, first search in the object namespace, and then search in the class namespace if they cannot be found (that is, the _dict of the object itself is preferred. If it is not found, the _dict of the class is preferred.)
New and classic
In Python 3.x, classical classes are cancelled. By default, they are all new classes, and there is no need to explicitly inherit object s, that is to say:
class Person(object): pass class Person(): pass # There is no difference between the three writing methods. The first one is recommended
However, in Python 2. X, classic classes are used by default. Only object s that explicitly inherit are new classes, that is:
class Person(object): pass # New class writing method class Person(): pass # Classical writing
The most obvious difference between them is that the order of inheritance search has changed, that is
- Multiple inheritance depth of classic classes takes precedence. First go deep into the left side of the inheritance tree and then return to start searching the right side
- New class multi inheritance breadth first, first find in the horizontal direction, and then find upward
Three characteristics of object oriented*
Inheritance, encapsulation, polymorphism
inherit
Previously, we learned about the relationship between objects and classes. Some attributes of objects actually come from classes. In fact, this is an inheritance relationship. In fact, there is an inheritance relationship between classes, which can share some class attributes
# Animal object class Animal: def __init__(self,name,age) self.name=name self.age=age def move(self): print('%s Moved'%self.name) # In fact, man is also an animal. When defining the human class, there are also animal attributes and methods # In order to improve efficiency, we can directly inherit animal objects, but different from animals, people can think class Person(Animal): def think(self): print('%s Think about it'%self.name) class Cat(Animal): pass class Dog(Animal): pass class BlackDog(Animal,Dog): pass ''' Take the example above: Aminal: Called parent class, base class, superclass Person,Cat,Dog: Subclass **Inherited classification** Single inheritance is to inherit only one class Person,Cat,Dog It's all single inheritance Multi inheritance is the integration of multiple classes, as described above BlackDog class View all parent classes: __bases__Method: such as Dog.__bases__ '''
Principle of inheritance: Diamond problem
''' Subclasses can obtain non private properties and non private methods of the parent class through inheritance without rewriting them themselves In the case of multiple inheritance, complex inheritance relationships will appear Diamond inheritance occurs: Diamond inheritance is also called diamond inheritance(Death diamond),In this structure, when D When an object of class uses a property, it will first D Class. If not, it will find the parent class. If not, it will continue to find the parent class of the parent class ''' # Detailed explanation of diamond inheritance problem: class A(): def __init__(self): print("get into A...") print("leave A...") class B(A): def __init__(self): print("get into B...") A.__init__(self) # This is one way to directly access the properties of the parent class print("leave B...") class C(A): def __init__(self): print("get into C...") A.__init__(self) print("leave C...") class D(B, C): def __init__(self): print("get into D...") B.__init__(self) C.__init__(self) print("leave D...") d = D() ''' Operation results get into D... get into B... get into A... leave A... leave B... get into C... get into A... leave A... leave C... leave D... above B Class and C Classes inherit A Class, D Class inherits B Class inherits again C Class, which forms a diamond inheritance relationship Creating D Class object, A Class__init__Method is executed twice, that is, in D Up B Yes A,Then it went up C Again A,This is obviously unreasonable. The simplest example is if A Class, which is executed twice ''' # Solving initialization problems: super # There are some differences in the usage of super between python3 and python2. In 2, super (B, self). _init_ (), which can be directly abbreviated as super (). _init_ () in 3 class A(): def __init__(self): print("get into A...") print("leave A...") class B(A): def __init__(self): print("get into B...") super(B,self).__init__() # This is one way to directly access the properties of the parent class print("leave B...") class C(A): def __init__(self): print("get into C...") super(C,self).__init__() print("leave C...") class D(B, C): def __init__(self): print("get into D...") super(D,self).__init__() print("leave D...") d = D() ''' Operation results get into D... get into C... get into B... get into A... leave A... leave B... leave C... leave D... super Principle of the method: In order to solve python The problem of repeated inheritance in multiple inheritance, python Used C3 Algorithm generated MRO List( Method Resolution Order Method resolution order), when multiple inheritance problems occur, C3 The algorithm calculates an inheritance order, super The method is based on MRO The order in the list ''' # How to view inheritance order - MRO list print(D.__mro__) # D here refers to the class name # It should be noted that the mro method can only be used for class objects, not instance objects
Depth first and breadth first
As can be seen from the above example, in the case of multiple inheritance, if a class inherits two classes, there will be two situations. Take a, B, C and D above as examples, the parent class of B has two choices: one is depth first, inherit a first, the other is breadth first, go C first, and finally go A. new classes are breadth first, and classical classes are depth first