面向过程和面向对象
一、面向过程
核心点在过程二字,过程指的是解决问题的步骤,说白了就是先做什么再干什么。这种解决问题的思路就好比是工厂中的流水线。shell脚本就是典型的面向过程,按步骤做事。
二、面向对象
核心点是对象二字,对象指的是具有相同属性和动作的结合体叫对象。面向对象编程就好比在代码中创造一个世界,创造若干对象,就像现实世界中的万物一样,每个物体都可以有自己的属性和动作。
类和对象
类是指具有相同属性和技能的一类事物,对象是指具体的类的表现,具体的实实在在的一个实例。比如动物时一个类,狗就是动物类的一个实例化对象。
1 2 3 4 5 6
| class Animal: pass
dog = Animal()
|
类体一共有两个部分,定义在类中变量叫做静态变量(又称变量或者静态字段),定义在类中的方法叫做动态变量(又称方法或者函数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Person: animal = "高级动物" soul = "有灵魂" language = "有语言"
def work(self): print("人类可以工作...")
def shop(self): print("人类可以购物...")
p1 = Person()
|
从类名的角度操作类中的内容
一、操作类中的静态变量
1 2 3 4 5 6 7 8 9 10 11 12
| class Person: animal = "高级动物" soul = "有灵魂" language = "有语言"
def work(self): print("人类可以工作...")
def shop(self): print("人类可以购物...")
|
- 通过__dict__来查看类中所有的内容,但是只能进行查询,不能对类中的内容进行增删改的操作
1 2 3 4 5 6 7 8 9 10 11 12
| print(Person.__dict__)
''' 获取到的内容是一个字典 {'__module__': '__main__', 'animal': '高级动物', 'soul': '有灵魂', 'language': '有语言', 'work': <function Person.work at 0x000001A89C34D8C8>, 'shop': <function Person.shop at 0x000001A89C34D9D8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None} '''
print(Person.__dict__["soul"])
Person.__dict__['soul'] = '行尸走肉'
|
- 通过
.
号来操作类中的静态变量,可以进行增删改查
1 2 3 4 5 6
| print(Person.soul) Person.mind = "有思想" Person.soul = "行尸走肉" del Person.animal
print(Person.__dict__)
|
二、操作类中的方法
从对象角度来操作类中的内容
在类中,名为__init__的函数称为类的初始化方法,在实例化一个对象时,实际上进行了以下操作:
- 创建了一个对象空间(实例空间)
- 自动执行类中的__init__方法,并将对象空间传给self参数
- 执行具体的__init__代码,给对象空间封装属性。
- 对象空间将空间指针返回给调用者,即自己定义的对象名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Person: animal = "高级动物" soul = "有灵魂" language = "有语言"
def __init__(self, name, age, sex): print(self) self.name = name self.age = age self.sex = sex
def work(self): print("人类可以工作...")
def shop(self): print("人类可以购物...") p1 = Person("cdc", 18, "male") print(p1)
|
一、操作对象中的静态变量
- 通过__dict__来查看对象中所有的内容,但是只能进行查询,不能对对象中的内容进行增删改的操作
- 通过
.
号来操作对象中的静态变量,可以进行增删改查;通过 . 号来操作类中的静态变量时,只能查询,不能进行其他操作。
1 2 3 4 5
| print(p1.name) p1.high = 175 del p1.name p1.age = 73 print(p1.__dict__)
|
二、操作对象的方法
类的名称空间和查询顺序
在定义一个类,到实例化一个对象,再到调用对象相关的静态变量或方法这个过程中,实际上经历了以下过程:
第一步,python解释器从上往下读取类的定义代码,读取完后会在内存中开辟一个存储类的名称空间;
第二部,执行实例化对象代码,会产生一个含有对象指针的名称空间,自动执行类中的__init__方法,并将对象空间传给self参数;
第三步,将实例化对象时传入的参数传给类中的构造函数;
第四步,执行具体的构造函数代码,给对象空间封装属性。
第五步,执行 print(p1.animal) 时,会先在对象的名称空间内进行查找 animal 属性,查找不到,再从类空间找,再找不到,再从父类找….
注意:
- 直接从类中查找属性时,先从本类空间找,如果找不到,再从父类找……
- 查找属性时可以从对象空间查找到类空间,但是不能从类空间往对象空间查找;
- 对象之间相互独立,对象空间之间相互对立。
组合
有这么一个需求,创建两个游戏角色,角色有名字、攻击力、生命值三个属性,角色可以互相攻击,此方法要完成谁攻击谁,谁掉了多少血, 还剩多少血’的提示功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class GameRole: def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp
def attack(self, obj): obj.hp = obj.hp - self.ad print(f"{self.name}攻击了{obj.name},{obj.name}掉了{self.ad}血,还剩{obj.hp}血")
p1 = GameRole("那鲁多", 10, 100) p2 = GameRole("萨斯给", 20, 80)
p1.attack(p2)
|
现在版本升级,角色可以使用武器,最后提示谁使用了哪种武器攻击了谁,谁掉了多少血还剩多少血
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class GameRole: def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp
def attack(self, obj): obj.hp = obj.hp - self.ad print(f"{self.name}攻击了{obj.name},{obj.name}掉了{self.ad}血,还剩{obj.hp}血")
class Weapon: def __init__(self, name, ad): self.name = name self.ad = ad
def fight(self, obj1, obj2): obj2.hp = obj2.hp - self.ad print(f"{obj1.name}使用了{self.name}攻击了{obj2.name},{obj2.name}掉了{self.ad}血还剩{obj2.hp}血")
p1 = GameRole("那鲁多", 10, 100) p2 = GameRole("萨斯给", 20, 80)
w1 = Weapon("苦无", 20) w2 = Weapon("手里剑", 10)
w1.fight(p1, p2)
|
虽然功能实现了,但是这样实现不合理,人物利用武器攻击别人,你的动作发起者是人,而不是武器。所以对于这种情况,可以用组合来解决。
组合:给一个类的对象封装一个属性,这个属性是另一个类的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class GameRole: def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp
def attack(self, obj): obj.hp = obj.hp - self.ad print(f"{self.name}攻击了{obj.name},{obj.name}掉了{self.ad}血,还剩{obj.hp}血")
def armament_weapon(self, weapon): self.weapon = weapon
class Weapon: def __init__(self, name, ad): self.name = name self.ad = ad
def fight(self, obj1, obj2): obj2.hp = obj2.hp - self.ad print(f"{obj1.name}使用了{self.name}攻击了{obj2.name},{obj2.name}掉了{self.ad}血还剩{obj2.hp}血")
p1 = GameRole("那鲁多", 10, 100) p2 = GameRole("萨斯给", 20, 80)
w1 = Weapon("苦无", 20) w2 = Weapon("手里剑", 10)
p1.armament_weapon(w1)
p1.weapon.fight(p1, p2)
|