1. Object oriented preliminary
The idea of object-oriented programming (OOP) is mainly designed for large-scale software.
1.1 difference between object-oriented and process oriented
- Process oriented thinking
Process oriented programming pays more attention to the "logical flow of the program", which is a kind of "executor" thinking, which is suitable for writing small-scale programs.
For example, how to drive? It's easy to list the implementation steps: 1 Start the car 2 Gear 3 step on the gas - Object oriented thinking
Object oriented pays more attention to the "relationship between objects in software", which is a kind of "designer" thinking, which is suitable for writing large-scale programs.
”For example, when we think about building a car, we will first think about "how to design a car?", Instead of "how to build a car step by step". Thinking about building a car in an object-oriented way, it is found that the car is composed of the following objects: 1 Tire 2 Engine 3 Shell 4 Seat 5 windshield
1.2 summary of object-oriented and process oriented
- They are both ways of thinking to solve problems and the way of code organization.
- Process oriented can be used to solve simple problems
- Solving complex problems: object-oriented grasp is used in the macro, and process oriented is still used in the micro processing.
1.3 evolution of objects
Starting from mainly dealing with simple data, evolve "array" as the data becomes more and more; Data types become complex and evolve into "structures"; The way and logic of processing data became complex, and "objects" evolved.
- Simple data
Figures like 30, 40 and 50.4 can be regarded as simple data. - array
Put data of the same type together. For example: integer array [20,30,40], floating point array [10.2, 11.3, 12.4], string array: [aa "," bb "," cc] - structural morphology
Putting different types of data together is the data structure in C language.
struct resume{ int age; char name[10]; double salary; };
- object
Putting different types of data and methods (i.e. functions) together is the object.
class Student: company = "SXT" #Class properties count = 0 #Class properties def __init__(self,name,score): self.name = name #Instance properties self.score = score Student.count = Student.count+1 def say_score(self): #Example method print("My company is:",Student.company) print(self.name,'Your score is:',self.score)
2. Definition of class
We compare the object to a "cookie", and the class is the "mold" that makes the cookie.
We define the attributes (data) and methods (behavior) of data types through classes, that is, "classes package behavior and state together".
When creating objects from a class, each object will share the behavior of the class (the methods defined in the class), but will have its own attribute value (not shared state). Method code is shared, but attribute data is not shared.
The syntax format of the definition class is as follows:
class Class name: Class body
The key points are as follows:
- The class name must conform to the rule of "identifier"; As a general rule, the first letter is capitalized, and the "Hump principle" is used for multiple words
- In the class body, we can define properties and methods
- Attributes are used to describe data, and methods (i.e. functions) are used to describe operations related to these data
[operation] definition of a typical class
class Student: def __init__(self,name,score): #The first parameter of the constructor must be self self.name = name #Instance properties self.score = score def say_score(self): #Example method print(self.name,'Your score is:',self.score) s1 = Student('Zhang San',80) #s1 is an instance object, which is called automatically__ init__ () method s1.say_score()
3. __init__ Construction method and__ new__ method
Class is abstract, also known as "object template". We need to create an instance object of the class through the class template, and then we can use the functions defined by the class.
A Python object contains the following parts:
- id (identity identification code)
- Type (object type)
- attribute (value) of object (method) (value): (method) (value)
To create an object, we need to define a constructor__ init__ () method. The construction method is used to perform "initialization of instance object", that is, after the object is created, initialize the relevant properties of the current object without return value.
The key points of init() are as follows:
- Fixed name, must be: init()
- The first parameter is fixed and must be: self. Self refers to the instance object just created.
- Constructors are usually used to initialize instance properties of instance objects. The following code initializes instance properties: name and score.
def __init__(self,name,score): self.name = name #Instance properties self.score = score
- The constructor is called by "class name (parameter list)". After calling, the created object is returned to the corresponding variable. For example: s1 = Student('zhang San ', 80)
- init() method: initialize the created object. Initialization refers to "assign value to instance attribute"
- new() method: used to create objects, but we generally do not need to redefine this method.
- If we don't define__ init__ Method, the system will provide a default__ init__ method. If we define a parameter__ init__ Method, the system does not create a default__ init__ method.
4. Instance attribute and instance method
4.1 instance properties
Instance properties are properties that are subordinate to instance objects, also known as "instance variables". The main points of his use are as follows:
- Instance properties are generally__ init__ () method is defined by the following code:
self.Instance property name = Initial value
- In other instance methods of this class, they are also accessed through self:
self.Instance property name
- After the instance object is created, access through the instance object:
obj01 = Class name() #Create object, call__ init__ () initialization properties obj01.Instance property name = value #You can assign a value to an existing attribute or add a new attribute
4.2 example method
Instance methods are methods that are subordinate to instance objects. The definition format of the instance method is as follows:
def Method name(self [, parameter list ]): Function body
The calling format of the method is as follows:
object.Method name([Argument list])
main points:
- When defining an instance method, the first parameter must be self. As before, self refers to the current instance object.
- When calling an instance method, you do not need or cannot pass parameters to self. Self is automatically passed by the interpreter
Differences between functions and methods
- Are used to complete a function of the statement block, the essence is the same.
- When a method is called, it is called through an object. Method is subordinate to a specific instance object, which is not characteristic of ordinary functions.
- Intuitively, self needs to be passed when defining methods, but not functions.
Method call essence of instance object
Other operations
- dir(obj) can obtain all attributes and methods of the object
- obj. Attribute dictionary of dict object
- pass empty statement
- Isinstance (object, type) determines whether the "object" is a "specified class"
5. Class object, class attribute, class method and static method
5.1 class objects
In the class definition format mentioned earlier, "class name:". In fact, when the interpreter executes a class statement, it creates a class object.
[operation] generation of test objects
class Student: pass #Empty statement print(type(Student)) print(id(Student)) Stu2 = Student s1 = Stu2() print(s1)
Operation results:
<class 'type'> 51686328 <__main__.Student object at 0x0000000002B5FDD8>
We can see that an object whose variable name is the class name "Student" is actually generated. We can also realize the relevant call by assigning a value to the new variable Stu2. Note that the "class object" is indeed created.
[note] pass is an empty statement. It means to do nothing but exist as a placeholder. When writing code, you can use pass first when you don't know what to add to the method or class for the time being
Class 5.2 attributes
Class attributes are attributes subordinate to class objects, also known as class variables. Because class attributes are subordinate to class objects, they can be shared by all instance objects.
How class attributes are defined:
class Class name: Class variable name= Initial value
In the class or outside the class, we can read and write through: "class name. Class variable name".
[operation] attribute usage test
class Student: company = "SXT" #Class properties count = 0 #Class properties def __init__(self,name,score): self.name = name #Instance properties self.score = score Student.count = Student.count+1 def say_score(self): #Example method print("My company is:",Student.company) print(self.name,'Your score is:',self.score) s1 = Student('Zhang San',80) #s1 is an instance object, which is called automatically__ init__ () method s1.say_score() print('Total creation{0}individual Student object'.format(Student.count))
Operation results:
My company is: SXT Zhang San's score is 80 A total of 1 was created Student object
Class 5.3 method
Class methods are methods that are subordinate to class objects. Class methods are defined by the decorator @ classmethod
Class method definition format is as follows:
@classmethod def Class method name(cls [,parameter list ]) : Function body
The key points are as follows:
- @classmethod must be on the line above the method
- The first cls must have; cls refers to the "class object" itself;
- Calling class method format: "class name. Class method name (parameter list)". In the parameter list, you do not need or cannot pass values to cls.
- Accessing instance properties and instance methods in class methods can cause errors
- When a subclass inherits a parent method, the cls passed in is a subclass object, not a parent object
[operation] method usage test
class Student: company = "SXT" #Class properties @classmethod def printCompany(cls): print(cls.company) Student.printCompany()
5.4 static method
Python allows you to define methods that are independent of "class objects", which are called "static methods".
"Static method" is no different from defining ordinary functions in the module, except that "static method" is placed in the "class namespace" and needs to be called through "class".
Static methods are defined by the decorator @ staticmethod. The format is as follows:
@staticmethod def Static method name([parameter list ]) : Function body
The key points are as follows:
- @staticmethod must be on the line above the method
- Calling static method format: "class name. Static method name (parameter list)".
- Accessing instance properties and instance methods in static methods can cause errors
[operation] static method usage test
class Student: company = "SXT" # Class properties @staticmethod def add(a, b): # Static method print("{0}+{1}={2}".format(a,b,(a+b))) return a+b Student.add(20,30)
6. Creation process of memory analysis instance object and class object (important)
Take the following code as an example to analyze the whole creation process, so that we can master the object-oriented concept more deeply:
class Student: company = "Shang Xuetang" #Class properties count = 0 #Class properties def __init__(self,name,score): self.name = name #Instance properties self.score = score Student.count = Student.count+1 def say_score(self): #Example method print("My company is:",Student.company) print(self.name,'Your score is:',self.score) s1 = Student('Gao Qi',80) #s1 is an instance object, which is called automatically__ init__ () method s1.say_score() print('Total creation{0}individual Student object'.format(Student.count)
7. __del__ Method (destructor) and garbage collection mechanism
__ del__ Method is called "destruct method", which is used to implement the operations required when the object is destroyed. For example, release the resources occupied by objects, such as open file resources, network connections, etc.
Python implements automatic garbage collection. When the object is not referenced (the reference count is 0), it is called by the garbage collector__ del__ method.
We can also delete the object through del statement to ensure the call__ del__ method.
The system will automatically provide__ del__ Method. Generally, there is no need to customize the destructor method.
#Destructor class Person: def __del__(self): print("Destroy object:{0}".format(self)) p1 = Person() p2 = Person() del p2 print("Program end")
Operation results:
Destroy object:<__main__.Person object at 0x02175610> Program end Destroy object:<__main__.Person object at 0x021755D0>
8. __call__ Methods and callable objects
Defined__ call__ The object of the method is called "callable object", that is, the object can be called like a function.
#Testing__ call__, Callable object class SalaryAccount: '''Salary calculation''' def __call__(self,salary): yearSalary = salary*12 daySalary = salary//30 hourSalary = daySalary//8 return dict(monthSalary=salary,yearSalary=yearSalary,daySalary=daySalary,hourSalary=hourSalary) s = SalaryAccount() print(s(5000)) #The of an object can be called like a function__ call__ method
Operation results:
{'monthSalary': 5000, 'yearSalary': 60000, 'daySalary': 166, 'hourSalary': 20
9. The method is not overloaded
In other languages, multiple methods with duplicate names can be defined as long as the method signature is unique. Method signature includes three parts: method name, parameter quantity and parameter type.
In Python, the parameters of a method have no declared type (the type of the parameter is determined when calling), and the number of parameters can also be controlled by variable parameters. Therefore, there is no method overload in Python. Defining a method can have multiple calling methods, which is equivalent to overloading methods in other languages.
If we define multiple methods with duplicate names in the class body, only the last method is valid.
Suggestion: do not use the method of duplicate names! Methods are not overloaded in Python.
#There is no method overload in Python. Define multiple methods with the same name, and only the last one is valid class Person: def say_hi(self): print("hello") def say_hi(self,name): print("{0},hello".format(name)) p1 = Person() #p1.say_hi() #No parameter, error reported: TypeError: say_hi() missing 1 required positional argument: 'name' p1.say_hi("Gao Qi")
10. Dynamic nature of the method
Python is a dynamic language. We can dynamically add new methods to classes or dynamically modify existing methods of classes.
#Dynamics of test methods class Person: def work(self): print("Work hard!") def play_game(self): print("{0}play a game".format(self)) def work2(s): print("Work hard and work hard!") Person.play = play_game Person.work = work2 p = Person() p.play() p.work()
We can see that Person dynamically adds play_game method and replacing work method with work2
11. Private attributes and private methods (implementation encapsulation)
Python has no strict access control restrictions on class members, which is different from other object-oriented languages. For private attributes and private methods, the following points are made:
- Generally, we agree that attributes starting with two underscores are private. Others are public.
- Private properties (Methods) can be accessed inside the class
- Private properties (Methods) cannot be accessed directly outside the class
- Private properties (Methods) can be accessed outside the class through "class name _ private property (method) name"
[note] methods are also attributes in essence! It's just that it can be executed through (). Therefore, the private attributes and public attributes mentioned here also explain the usage of private methods and public methods. The following tests also include examples of private and public methods.
[test] private attribute and public attribute usage test
#Test private properties and methods
class Employee: __company = "Baizhan programmer" #Private class properties You can find it through dir_ Employee__company def __init__(self,name,age): self.name = name self.__age = age #Private instance properties def say_company(self): print("My company is:",Employee.__company) #Private properties can be accessed directly inside the class print(self.name,"Your age is:",self.__age) self.__work() def __work(self): #Private instance methods can be found through dir_ Employee__work print("Work! Work hard, make money and marry a daughter-in-law!") p1 = Employee("Gao Qi",32) print(p1.name) print(dir(p1)) # p1.say_company() print(p1._Employee__age) #In this way, private properties can be accessed directly. Attributes can be found through dir:_ Employee__age #print(p1.__age) #Directly access private properties and report an error #p1.__sleep() #Directly access private methods and report errors
Operation results:
Gao Qi ['_Employee__age', '_Employee__company', '_Employee__work', '__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__', 'name', 'say_company'] My company is: Baizhan programmer Gao Qi's age is 32 Work! Work hard, make money and marry a daughter-in-law! 32
We can see from all the properties of the printed Person object. The private attribute "_age" is actually stored according to the attribute "_Person__age". This is the fundamental reason why we can't use "_age" directly, but can use "_Person__age"
12. @property decorator
@Property can change the calling mode of a method into "property call". Here's a simple example to make it big
Experience this shift at home:
#Simple test @ property class Employee: @property def salary(self): return 30000; emp1 = Employee() print(emp1.salary) #Print 30000 print(type(emp1.salary)) #Print < class' Int '> #emp1.salary() #Error reporting: TypeError: 'int' object is not callable #emp1.salary =1000 #@The property modified by property is read-only if no setter method is added. Modify the error attributeerror here: can't set attribute
@property is mainly used to help us deal with the read and write operations of properties. For a certain attribute, we can directly use: emp1 salary = 30000
The above operations include read and write operations. However, this practice is not safe. For example, I need to limit my salary to 1-10000. At this time, we need to handle it through getter and setter methods.
#Test @ property class Employee: def __init__(self,name,salary): self.name = name self.__salary = salary @property #getter method equivalent to salary attribute def salary(self): print("The monthly salary is{0},The annual salary is{1}".format(self.__salary,(12*self.__salary))) return self.__salary; @salary.setter def salary(self,salary): #setter method equivalent to salary attribute if(0<salary<1000000): self.__salary = salary else: print("Salary entry error! Only in 0-1000000 between") emp1 = Employee("Gao Qi",100) print(emp1.salary) emp1.salary = -200
Operation results:
The monthly salary is 100,The annual salary is 1200 100 The monthly salary is 100,The annual salary is 1200 100 Salary entry error! Only in 0-1000000 between
13. Practical operation
Design a rectangle class named MyRectangle to represent the rectangle. This class contains:
(1) Coordinates of the top left vertex: x, y
(2) Width and height: width, height
(3) Construction method: pass in X, y, width and height. If (x, y) is not transmitted, it defaults to 0. If width and height are not transmitted, it defaults to 100
(4) Define a method to calculate the area with getArea()
(5) Define a method of calculating perimeter with getPerimeter()
(6) Define a draw() method to draw the rectangle with turtle drawing
import turtle class MyRectangle: def __init__(self,x=0,y=0,width=100,height=100): #Focusing on this structure, x=0,y=0 and other operations realize the requirements of default value without transmitting value self.x = x self.y = y self.width = width self.height = height def getArea(self): #Calculated area print(self.width*self.height) def getPerimeter(self): #Calculated perimeter print(self.width*2+self.height*2) def draw(self): #Turtle Graphics turtle.goto(self.x,self.y) turtle.forward(self.width) turtle.left(90) turtle.forward(self.height) turtle.left(90) turtle.forward(self.width) turtle.goto(self.x,self.y) my=MyRectangle() my.getArea() my.getPerimeter() my.draw()