catalogue
1. Object oriented and process oriented
3. Object oriented basic syntax
(1) Create class (method only)
(3) Introduction to initialization method
(4)__ del__ Method introduction
4. Object oriented encapsulation
5. Object oriented private attributes and private methods
6. Object oriented inheritance
1, Decorator supplement
Decorator belt parameters
Let's write a decorator with parameters first, and then explain it
def func_arg(name): def func_out(func): def wrapped_func(): print('This is a decorator') print('Executing decorated function...') func() print('Outputting parameters for decorator...') print(name) return wrapped_func return func_out @func_arg('world') def f(): print('hello') f() ''' This is a decorator Executing decorated function... hello Outputting parameters for decorator... world '''
1. Execute @ func_arg('world '), call func_arg function and pass' world 'as a parameter to name. Enter func after calling_ Arg executes programs from top to bottom internally.
2. Execute func_ Def func inside ARG_ Out (func): defines func_outer function, func_ The out function is loaded into memory
3. Execute func_ Return func inside ARG_ Out, func_ A reference to the out function is returned to func_ Caller of Arg function: @ func_arg('world '), so the logic of the code becomes
def func_out(func): def wrapped_func(): print('This is a decorator') print('Executing decorated function...') func() print('Outputting parameters for decorator...') print(name) # The value of name is already in memory return wrapped_func @func_out def f(): print('hello') f()
Here is the normal decorator we are familiar with
2, Object oriented
1. Object oriented and process oriented
Process oriented:
Process oriented is different from object-oriented. Process oriented analyzes the steps needed to solve the problem, and then uses functions to realize these steps step by step. When using, it can be called one by one.
object-oriented:
Object oriented is to decompose the problem transaction into various objects. The purpose of establishing objects is not to complete a step, but to describe the behavior of something in the whole problem-solving step.
difference:
In short: the program written in the process oriented method is an egg fried rice, while the program written in the object-oriented method is a cover rice. The so-called cover rice is to pour a cover dish on the rice. You can pour whatever dish you like. I think this metaphor is more appropriate.
I don't know the details of fried rice with eggs, because I haven't been a cook and can't cook, but the last process must be to mix rice and eggs and stir well. If you want a braised meat covered rice, you will be watered with a braised meat; If you want a green pepper potato to water the rice, pour a green pepper potato shred.
The advantage of fried rice with eggs is that it tastes even and tastes delicious. If it happens that you don't like eggs and only vegetables, the only way is to pour them all out and make a new fried rice with vegetables. It's not so much trouble to cover the rice. You just need to remove the cover and replace it with a cover. The disadvantage of covered rice is that it tastes uneven. It may not be as fragrant as egg fried rice.
Is it better to stir fry rice with eggs or water rice? In fact, such questions are difficult to answer. If you have to compare up and down, you must set a scene, otherwise you can only say that they have their own strengths. Well, from the restaurant point of view, cooking covered rice obviously has more advantages than egg fried rice. He can combine as many combinations as he wants without wasting.
The advantage of covered rice is the separation of "food" and "rice", which improves the flexibility of making covered rice. If you are not satisfied with the food, change the food. If you are not satisfied with the food, change the food. In the professional term of software engineering, "maintainability" is better, and the coupling degree of "rice" and "dish" is relatively low. Egg fried rice mixes "egg" and "rice". It is difficult to change any of "egg" and "rice", and the coupling degree is very high, so that the "maintainability" is poor. One of the goals of software engineering is maintainability, which is mainly reflected in three aspects: comprehensibility, testability and modifiability. One of the benefits of object-oriented is that it significantly improves the maintainability of software system.
2. Class and object
Class: something with the same characteristics (properties in programming) and behavior (Methods in programming)
This kind of popular understanding can be the drawings and templates for manufacturing aircraft (can not be used directly)
Object: the specific existing things created by the class (which can be used directly), and the properties and methods of which class are created
When we get a requirement, we should first analyze which classes need to be created: for example, to develop a plant vs. zombie game, the main classes are: plant class and zombie class, and then analyze the attributes (i.e. what are the same characteristics of this class) and methods (i.e. what are the same behaviors of this class)
Note: the naming of the class should meet the big hump naming method: the first letter of each word should be capitalized
3. Object oriented basic syntax
(1) Create class (method only)
class Class name: def Method 1(self, parameter list): pass def Method 2(self, parameter list): pass
Self is a required parameter, and self represents the object itself
(2) Create object
Object name = Class name()
Example: the kitten likes to eat fish, and the kitten is drinking water
class Cat: def eat(self): print('The kitten is eating fish') def drink(self): print('The kitten is drinking water') little_cat = Cat() little_cat.eat() # The kitten is eating fish little_cat.drink() # The kitten is drinking water
If the kitten has a name, Tom, as if his name is an attribute, we can modify the code at this time
class Cat: def eat(self): print(f'{self.name}Eating fish') def drink(self): print(f'{self.name}Drinking water') little_cat = Cat() little_cat.name = 'Tom' little_cat.eat() # Tom is eating fish little_cat.drink() # Tom is drinking water
The above is to add attributes to the object outside the class. If the code is modified to the following, it will report an error. Therefore, adding attributes outside the class is not recommended
class Cat: def eat(self): print(f'{self.name}Eating fish') def drink(self): print(f'{self.name}Drinking water') little_cat = Cat() little_cat.eat() little_cat.drink() little_cat.name = 'Tom'
(3) Introduction to initialization method
class Cat: def __init__(self): print('This is an initialization method') def eat(self): print(f'{self.name}Eating fish') def drink(self): print(f'{self.name}Drinking water') little_cat = Cat() # This is an initialization method
The initialization method is automatically called when the object is created:__ init__ method
Therefore, we can add properties to the class by passing parameters to the initialization method, so that its properties will be automatically initialized when the object is created
class Cat: def __init__(self,name): # Property name of object = parameter name self.name = name def eat(self): print(f'{self.name}Eating fish') def drink(self): print(f'{self.name}Drinking water') little_cat = Cat('Tom') little_cat.eat() # Tom is eating fish little_cat.drink() # Tom is drinking water big_cat = Cat('Jerry') big_cat.eat() # Jerry is eating fish big_cat.drink() # Jerry is drinking water
(4)__ del__ Method introduction
This method will be called automatically before the object is destroyed from the internal address (it can be understood as the last contribution before death)
class Cat: def __init__(self, name): self.name = name def eat(self): print(f'{self.name}Eating fish') def drink(self): print(f'{self.name}Drinking water') def __del__(self): print(f'{self.name}Run away') little_cat = Cat('Tom') little_cat.eat() # Tom is eating fish little_cat.drink() # Tom is drinking water big_cat = Cat('Jerry') big_cat.eat() # Jerry is eating fish big_cat.drink() # Jerry is drinking water print('*' * 50) ''' Tom Eating fish Tom Drinking water Jerry Eating fish Jerry Drinking water ************************************************** Tom Run away Jerry Run away '''
We found that when the program is finished, big_cat and little_cat is automatically destroyed and executed__ del__ method
We can also delete it manually
class Cat: def __init__(self, name): self.name = name def eat(self): print(f'{self.name}Eating fish') def drink(self): print(f'{self.name}Drinking water') def __del__(self): print(f'{self.name}Run away') little_cat = Cat('Tom') little_cat.eat() # Tom is eating fish little_cat.drink() # Tom is drinking water big_cat = Cat('Jerry') big_cat.eat() # Jerry is eating fish big_cat.drink() # Jerry is drinking water del little_cat print('*' * 50) ''' Tom Eating fish Tom Drinking water Jerry Eating fish Jerry Drinking water Tom Run away ************************************************** Jerry Run away '''
We manually deleted little before printing *_ Cat variable, he executes it__ del__ Method, big_cat is automatically destroyed after the program is executed__ del__ method
(5)__ str__ method
class Cat: def __init__(self, name): self.name = name def eat(self): print(f'{self.name}Eating fish') def drink(self): print(f'{self.name}Drinking water') def __del__(self): print(f'{self.name}Run away') little_cat = Cat('Tom') print(little_cat) # <__main__.Cat object at 0x000001832B989190> little_cat.eat() # Tom is eating fish little_cat.drink() # Tom is drinking water
We're joining__ str__ Method, print the variable name of the object, and you will find that the output is the address of the object in memory
class Cat: def __init__(self, name): self.name = name def __str__(self): return f'The cat's name is{self.name}' def eat(self): print(f'{self.name}Eating fish') def drink(self): print(f'{self.name}Drinking water') def __del__(self): print(f'{self.name}Run away') little_cat = Cat('Tom') print(little_cat) # The cat's name is Tom little_cat.eat() # Tom is eating fish little_cat.drink() # Tom is drinking water
When we set__ str__ Method, and then print the variable name of the object. The output is__ str__ Contents of return in method
4. Object oriented encapsulation
Demand: Xiao Ming weighs 75kg, loses 0.5kg every time he runs, and gains 1kg every time he eats
class Person: def __init__(self, name, weight): self.name = name self.weight = weight def __str__(self): return f'I am{self.name},My weight is{self.weight}' def run(self): # One call, weight loss 0.5 print('run...') self.weight -= 0.5 def eat(self): # Call once, weight gain 1 print('eat...') self.weight += 1 def __del__(self): print(f'{self.name}What's your weight now{self.weight}') xiaoming = Person('Xiao Ming', 75) xiaoming.run() # run... xiaoming.run() # run... xiaoming.eat() # eat print(xiaoming) # I'm Xiao Ming. My weight is 75.0 xiaoming.run() # run... xiaoming.eat() # eat xiaoming.eat() # eat xiaoming.eat() # eat print('*' * 50) # Xiao Ming now weighs 77.5
Demand: the House has House type, total area and furniture name list. There is no furniture in the new House. The furniture (HouseItem) has furniture name and floor area, of which bed covers an area of 4 square meters, chest covers an area of 2 square meters and table covers an area of 2.5 square meters. Add the above three pieces of furniture to the House. When printing the House, it is required to output the House type, Total area, remaining area, furniture name list
analysis:
House class: attribute: area, house type, furniture name list, remaining area} method: initialization method, str method, add furniture method
HouseItem class: attribute: name, method: initialization method, str method
Because furniture is used in the House class, develop the HouseItem class first
class HouseItem: def __init__(self, name, area): """ :param name: Furniture name :param area: area covered """ self.name = name self.area = area def __str__(self): return '[%s] The floor area is %.2f square metre' % (self.name, self.area) # Create furniture bed = HouseItem('Simmons', 4) chest = HouseItem('wardrobe', 2) table = HouseItem('table', 2.5) print(bed) print(chest) print(table) class House: def __init__(self, house_type, area): """ :param house_type: House type :param area: total area """ self.house_type = house_type self.area = area # The remaining area is consistent with the total area by default self.free_area = area # Furniture name list (no furniture by default) self.item_list = [] def __str__(self): return ("House type:%s\n total area:%.2f square metre[Remaining area:%.2f square metre]\n Furniture name:%s" % (self.house_type, self.area, self.free_area, self.item_list)) def add_item(self, item): print("To add%s" % item) # 1. Judge whether the area of furniture is greater than the remaining area if item.area > self.free_area: print("To add%s The area is too large to add" % item.name) return # 2. Add the name of the furniture to the list self.item_list.append(item.name) # 3. Calculate the remaining area self.free_area -= item.area my_home = House("two bedrooms ", 60) my_home.add_item(bed) my_home.add_item(chest) my_home.add_item(table) print(my_home)
5. Object oriented private attributes and private methods
Some properties or methods of an object only want to be used inside the object, not accessed outside
Definition: add two underscores before the property name or method name
class Girl: def __init__(self, name, age): self.name = name # Define private properties self.__age = age # Define private methods def __secret(self): print(f'{self.name}What is your age{self.__age}') xiaomei = Girl('Xiaomei', 20) print(xiaomei.name) # Xiaomei print(xiaomei.__age) # report errors xiaomei = Girl('Xiaomei', 20) xiaomei.__secret() # report errors
We can see that the output name attribute can be output normally, but we have clearly defined it__ age attribute, but an error is reported in the output
class Girl: def __init__(self, name, age): self.name = name # Define private properties self.__age = age # Define private methods def __secret(self): print(f'{self.name}What is your age{self.__age}') xiaomei = Girl('Xiaomei', 20) xiaomei.__secret() # report errors
Similarly, an error will be reported when calling a private method
However, there is no real private property in python, and we still have a way to access private properties and private methods
class Girl: def __init__(self, name, age): self.name = name # Define private properties self.__age = age # Define private methods def __secret(self): print(f'{self.name}What is your age{self.__age}') xiaomei = Girl('Xiaomei', 20) print(xiaomei._Girl__age) # 20
We're calling__ Add before age attribute_ Class name, you can use private properties
class Girl: def __init__(self, name, age): self.name = name # Define private properties self.__age = age # Define private methods def __secret(self): print(f'{self.name}What is your age{self.__age}') xiaomei = Girl('Xiaomei', 20) xiaomei._Girl__secret() # Xiaomei's age is 20
We're calling__ Add before the secret method_ Class name, you can call private methods
6. Object oriented inheritance
Inheritance: a subclass has all the properties and methods of its parent class
class Animal: def eat(self): print('eat') def sleep(self): print('sleep') class Dog: def eat(self): print('eat') def sleep(self): print('sleep') dog = Dog() dog.eat() # eat dog.sleep() # sleep
Dogs belong to animals. Animals can eat and sleep, and dogs can eat and sleep. Since dogs belong to animals, is there a way not to redefine a method of eating and sleeping in dogs (to avoid code redundancy)? This requires the use of inheritance
Use inheritance development:
class Animal: def eat(self): print('eat') def sleep(self): print('sleep') # Subclass (inherited parent) class Dog(Animal): # You can add subclass specific methods def bark(self): print('bark') dog = Dog() dog.eat() # eat dog.sleep() # sleep dog.bark() # bark
It can be seen that we do not define eat and sleep methods in dogs that inherit Animal classes, but we can call eat and sleep methods in the parent class (Animal class)
class Animal: def eat(self): print('eat') def sleep(self): print('sleep') # Subclass (inherited parent) class Dog(Animal): # You can add subclass specific methods def bark(self): print('bark') class XiaoTianQuan(Dog): def fly(self): print('fly') dog = XiaoTianQuan() dog.eat() # eat dog.sleep() # sleep dog.bark() # bark dog.fly() # fly
We also defined a dog class to inherit from dogs, while dogs inherit from animals. We found that the dog class object can call the methods of the parent class, indicating that inheritance is transitive
Method override
What should we do when the methods in the parent class are not satisfied with the requirements of the child class?
1. Method of overriding parent class
class Dog(Animal): # You can add subclass specific methods def bark(self): print('bark') class XiaoTianQuan(Dog): def fly(self): print('fly')
For example, the barking of a dog is different from that of a dog. What should we do?
class Dog(): # You can add subclass specific methods def bark(self): print('bark') class XiaoTianQuan(Dog): def fly(self): print('fly') def bark(self): print('Howling dog bark') dog = XiaoTianQuan() dog.bark() # Barker's Barker
We can define another bark method in the howling Dog class when executing dog When barking (), it will first find the barking method of the subclass. If it is found, it will execute the barking method of the subclass. If the subclass does not find the barking method of the parent class. This is the first method of method Rewriting: overriding the method of the parent class
2. Extend parent method
If the methods of the parent class cannot fully meet the requirements (only part of the requirements can be met), the methods of the parent class must be extended in the child class. How to implement this?
class Dog(): # You can add subclass specific methods def bark(self): print('bark') class XiaoTianQuan(Dog): def fly(self): print('fly') def bark(self): super().bark() print('Howling dog bark') dog = XiaoTianQuan() dog.bark() ''' bark Howling dog bark '''
A bark method is also defined in the subclass, using super() The parent method name () calls the parent class method name, and then increases the unique requirement of the subclass. In the end, after calling the bark method after the object is created, it calls the bark method that extends the parent class bark in the subclass.
Note: when there are private methods and properties in the parent class, the child class cannot directly inherit the private properties and methods of the parent class. If you want to use them, you can use the methods described above.
Multiple inheritance
If a subclass inherits from more than one parent class, it is called multi inheritance
class A(object): def test(self): print('A---test') def demo(self): print('A---demo') class B(object): def demo(self): print("B---demo") def test(self): print('B---test') class C(B, A): pass c = C() c.test() # B---test c.demo() # B---demo
Note: when there are methods with the same name in multiple parent classes inherited by the child class, and we call this method, the method of the first parent class in parentheses will be executed first
7. Polymorphism
Different subclasses call the same parent method to produce different results, which is called polymorphism
prerequisite:
1. Inheritance: polymorphism must occur between subclasses and parents;
2. Override: the subclass overrides the method of the parent class.
class WhoSay: def say(self,who): who.say() class CLanguage: def say(self): print("Called is Clanguage Class say method") class CPython(CLanguage): def say(self): print("Called is CPython Class say method") class CLinux(CLanguage): def say(self): print("Called is CLinux Class say method") a = WhoSay() #Call the say() method of the CLanguage class a.say(CLanguage()) #Call the say() method of CPython class a.say(CPython()) #Call the say() method of the CLinux class a.say(CLinux()) ''' Called is Clanguage Class say method Called is CPython Class say method Called is CLinux Class say method '''