Introduction
Suppose we want to develop a game about airplane battle, there will be two roles in the game, one is the player-operated fighter and the other is the enemy's fighter. Both fighters have different skills or attacking styles. Now we write the following codes with what we have learned:
def Fighter(name,atk,hp,speed): fighter = { 'name' : name, #The name of the aircraft 'atk' : atk, #Attacking power of warplanes 'hp' : hp, #The blood volume of a fighter 'speed' : speed #The speed of a fighter } return fighter def EnemyFighter(name,atk,hp,speed,kind): enemyfighter = { 'name' : name, #The name of the enemy aircraft 'atk' : atk, #Attack power of enemy aircraft 'hp' : hp, #Enemy Aircraft Blood Volume 'speed' : speed, #Enemy Aircraft Speed 'kind' : kind #Types of enemy aircraft } return enemyfighter
Once we have written these attributes, we can generate enemy and player fighters:
playerFighter1 = Fighter('Player1',200,1500,300) playerFighter2 = Fighter('Player2',150,2000,280) Boss1 = EnemyFighter('lazerBoss',1000,7000,50,'Boss') Monster1 = EnemyFighter('Monster1',100,200,150,'Monster') print(playerFighter1) #{'name': 'Player1', 'atk': 200, 'hp': 1500, 'speed': 300} print(playerFighter2) #{'name': 'Player2', 'atk': 150, 'hp': 2000, 'speed': 280} print(Boss1) #{'name': 'lazerBoss', 'atk': 1000, 'hp': 7000, 'speed': 50, 'kind': 'Boss'} print(Monster1) #{'name': 'Monster1', 'atk': 100, 'hp': 200, 'speed': 150, 'kind': 'Monster'}
So after these objects have been generated, what we still lack is their different attack methods, so we need to add another method to their methods and call them again
def Fighter(name,atk,hp,speed): #Define the attributes of a fighter fighter = { 'name' : name, #The name of the aircraft 'atk' : atk, #Attacking power of warplanes 'hp' : hp, #The blood volume of a fighter 'speed' : speed, #The speed of a fighter } def playerAttack(enemyfighter): #Player Attack Function enemyfighter['hp'] -= fighter['atk'] print('{0}cover{1}Attacked,Lost{2}HP!'.format(enemyfighter['name'],fighter['name'],fighter['atk'])) fighter['playerAttack'] = playerAttack return fighter def EnemyFighter(name,atk,hp,speed,kind): enemyfighter = { 'name' : name, #The name of the enemy aircraft 'atk' : atk, #Attack power of enemy aircraft 'hp' : hp, #Enemy Aircraft Blood Volume 'speed' : speed, #Enemy Aircraft Speed 'kind' : kind #Types of enemy aircraft } def enemyFighterAttack(fighter): #Enemy Attack Function fighter['hp'] -= enemyfighter['atk'] print('{0}cover{1}Attacked,Lost{2}HP!'.format(fighter['name'],enemyfighter['name'],enemyfighter['atk'])) enemyfighter['enemyFighterAttack'] = enemyFighterAttack return enemyfighter playerFighter1 = Fighter('Player1',200,1500,300) playerFighter2 = Fighter('Player2',150,2000,280) Boss1 = EnemyFighter('lazerBoss',1000,7000,50,'Boss') Monster1 = EnemyFighter('Monster1',100,200,150,'Monster') print(playerFighter1) #{'name': 'Player1', 'atk': 200, 'hp': 1500, 'speed': 300, 'playerAttack':
<function Fighter.<locals>.playerAttack at 0x0000000002138A60>} print(playerFighter2) #{'name': 'Player2', 'atk': 150, 'hp': 2000, 'speed': 280, 'playerAttack':
<function Fighter.<locals>.playerAttack at 0x0000000002138D08>} print(Boss1) #{'name': 'lazerBoss', 'atk': 1000, 'hp': 7000, 'speed': 50, 'kind': 'Boss', 'enemyFighterAttack':
<function EnemyFighter.<locals>.enemyFighterAttack at 0x0000000002138D90>} print(Monster1) #{'name': 'Monster1', 'atk': 100, 'hp': 200, 'speed': 150, 'kind': 'Monster', 'enemyFighterAttack':
<function EnemyFighter.<locals>.enemyFighterAttack at 0x0000000002138E18>}
Now call these two function codes:
print(playerFighter1) #{'name': 'Player1', 'atk': 200, 'hp': 1500, 'speed': 300, 'playerAttack':
<function Fighter.<locals>.playerAttack at 0x0000000002138A60>} Boss1['enemyFighterAttack'](playerFighter1) #Player1 cover lazerBoss Attacked,1000 lost HP! print(playerFighter1) #{'name': 'Player1', 'atk': 200, 'hp': 500, 'speed': 300, 'playerAttack':
<function Fighter.<locals>.playerAttack at 0x00000000027A8A60>} print(Monster1) #{'name': 'Monster1', 'atk': 100, 'hp': 200, 'speed': 150, 'kind': 'Monster', 'enemyFighterAttack':
<function EnemyFighter.<locals>.enemyFighterAttack at 0x0000000002138E18>} playerFighter2['playerAttack'](Monster1) #Monster1 cover Player2 Attacked,Lost 150 HP! print(Monster1) #{'name': 'Monster1', 'atk': 100, 'hp': 50, 'speed': 150, 'kind': 'Monster', 'enemyFighterAttack':
<function EnemyFighter.<locals>.enemyFighterAttack at 0x00000000027A8E18>}
Like the Fighter and EnemyFighter functions above, they both define a kind of thing, and it's not until we call a function and assign it that we really have a real thing
Object-oriented, process-oriented, function-oriented
Object-oriented: Encapsulates the entire task into a large class, in which each step is broken down and executed in detail. Only the execution class is needed to complete the task.The advantage is that it solves the extensibility of the program. Modifying an object individually will immediately be reflected in the whole system, such as modifying the characteristics and skills of a character parameter in a game.The disadvantage is that poor controllability, unlike process-oriented programming pipelining, can accurately predict the process and results of a problem. Once an object-oriented program starts, it is solved by the interaction between objects, even God cannot predict the results.So often we see a new character appear in the game with scenes that affect the balance of the game and the gamer's experience.
Process-oriented: is that the program is executed step by step.The advantage is that it greatly reduces the complexity of writing programs, as long as the code is stacked along the steps to be executed.
The disadvantage is that a set of pipelining or processes is to solve a problem, and the code is all in one go.
Function-oriented: Programming is divided into many situations, each of which is written as a function, and then the function is executed step by step.
class
class Cat: def __init__(self,*args): self.name = args[0] self.height = args[1] self.weight = args[2] self.type = args[3]
Instantiate an object to see its internal properties (usage: object name. property name)
cat1 = Cat('jackey',20,45,'cat') #Instantiate an object print(cat1.name) #jackey print(cat1.height) #20 print(cat1.weight) #45 print(cat1.type) #cat
You can also view attributes by instantiating the name. u dict_u[attribute name]
print(cat1.__dict__['name']) #jackey print(cat1.__dict__['height']) #20 print(cat1.__dict__['weight']) #45 print(cat1.__dict__['type']) #cat
Viewing attributes using self. u dict_u
class Cat: def __init__(self,*args): print(self.__dict__) #{} When we haven't added attributes yet,self No Content self.name = args[0] self.height = args[1] self.weight = args[2] self.type = args[3] print(self.__dict__) #{'name': 'jackey', 'height': 20, 'weight': 45, 'type': 'cat'} cat1 = Cat('jackey',20,45,'cat') #Instantiate an object print(cat1.__dict__) #{'name': 'jackey', 'height': 20, 'weight': 45, 'type': 'cat'}
The parameter self in u init_() can be interpreted as a dictionary, that is, an object, in which the following attributes, name, height, weight, etc., all exist in this self'dictionary, and each attribute and its corresponding value are given to the object we instantiate
class Cat: def __init__(self,*args): self.name = args[0] self.height = args[1] self.weight = args[2] self.type = args[3] print(self,id(self)) #<__main__.Cat object at 0x00000000025B1DD8> 39525848 cat1 = Cat('jackey',20,45,'cat') #Instantiate an object print(cat1,id(cat1)) #<__main__.Cat object at 0x00000000025B1DD8> 39525848
You can see from the execution that they share the same memory address
View the static properties (usage: class name. static properties) and invocation methods (usage: object name. method name ()) inside a class function:
class Cat: Rose = 'cat' #Static Properties def __init__(self,*args): self.name = args[0] self.height = args[1] self.weight = args[2] self.type = args[3] def Eat(self): print('What to eat...') cat1 = Cat('jackey',20,45,'cat') #Instantiate an object print(Cat.Rose) #cat cat1.Eat() #What to eat...
Class name. u dict_u
Instance name. u dict_u It stores properties inside self
And the class name. u dict_u It stores all the names in this class
print(Cat.__dict__) #{'__module__': '__main__', '__init__': <function Cat.__init__ at 0x0000000002588950>, 'Eat': <function Cat.Eat at 0x0000000002588A60>, '__dict__': <attribute '__dict__' of 'Cat' objects>, '__weakref__': <attribute '__weakref__' of 'Cat' objects>, '__doc__': None} print(cat1.__dict__) #'name': 'jackey', 'height': 20, 'weight': 45, 'type': 'cat'}
Execution process description:
class Cat: def __init__(self,*args): self.name = args[0] self.height = args[1] self.weight = args[2] self.type = args[3] def Eat(self): print('{}Eating dried fish...'.format(self.name)) cat1 = Cat('jackey',20,45,'cat') #Instantiate an object #Both of these function call methods are possible #Cat.Eat(cat1) #jackey is eating dried fish... cat1.Eat() #jackey Eating dried fish...
1. First, a Cat class is defined
2.Cat() means that calling the class name with parentheses and content is equivalent to executing the u init_() function
3. All parameters in Cat() are received as meta-ancestors by *args, and self is a dictionary-like object created by itself within a function
4. Then execute the assignment process self.name = args[0]... instruct all attribute assignments to complete
5. At this time, the self parameter will pass the value of all the attributes to the object cat1 we instantiated outside. Note: if there is no value inside the self, there is no content outside the instantiated object
6. Finally, call the function by class. function name (instantiated object name) or instantiated object name. function name (), execute the Eat method, and print the result
modify attribute
print(cat1.name) #jackey cat1.name = 'Maria' print(cat1.name) #Maria print(cat1.__dict__) #{'name': 'Maria', 'height': 20, 'weight': 45, 'type': 'cat'}
It can also be modified with u dict_u
print(cat1.name) #jackey cat1.__dict__['name'] = 'Maria' print(cat1.name) #Maria print(cat1.__dict__) #{'name': 'Maria', 'height': 20, 'weight': 45, 'type': 'cat'}
Add a new attribute
class Cat: def __init__(self,*args): self.name = args[0] self.height = args[1] self.weight = args[2] self.type = args[3] def Eat(self): print('{}Eating dried fish...'.format(self.name)) cat1 = Cat('jackey',20,45,'cat') #Instantiate an object print(cat1.__dict__) #{'name': 'jackey', 'height': 20, 'weight': 45, 'type': 'cat'} cat1.age = 5 print(cat1.age) #5 print(cat1.__dict__) #{'name': 'jackey', 'height': 20, 'weight': 45, 'type': 'cat', 'age': 5}
Other class properties
Class name. u name_u #Class name (string) Class name. u doc_u #Document string for class Class name. u base_ First parent of the class (when talking about inheritance) Class name. u bases_u Tuples of all parent classes of the class (when talking about inheritance) Class name. u dict_u #Dictionary properties of the class Class name. u module_u #Module where the class definition is located Class Name. u class_u Instance corresponding class (only in newer classes)
summary
What is a class? A class of things with the same characteristics (people, dogs, cats, airplanes, etc.)
What is the object? Something specific (the person in room 303, the pen, etc.)
What is instantiation? Classes - > Object Procedures
Everything in python is an object, and the nature of a type is a class
When will object-oriented be used? For example, it is very obvious to deal with a class of things that have similar properties and functions; when several functions need to pass in the same parameters repeatedly, you can consider object-oriented; these parameters are properties of the object
Practice
Represent the perimeter and area of a circle in an object-oriented way, and find out its perimeter and area
from math import pi as P class Circle: def __init__(self,r): self.r = r def S(self): return P*self.r**2 def L(self): return 2*P*self.r c1 = Circle(1) print(c1.S()) #3.141592653589793 print(c1.L()) #6.283185307179586