一.面向过程的程序设计&面向对象的程序设计
1.面向过程的程序设计:核心是过程
优点:复杂度的问题流程化,进而简单化,具体点就是一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将会非常简单
缺点:一套流程是解决一类问题的,如果是解决另外一类就是大改,牵一发动全身
应用场景:一旦完成基本很少改变的场景,著名例子有linux内核,git等
2.面向对象的程序设计:核心是对象
优点:解决了程序的扩展性,例如:对某一个对象单独修改,会立刻反映到整个体系中
缺点:编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等
二.类与对象
类:把一类事物的相同特征和动作整合到一起就是类,类是抽象的概念
对象:就是基于类而创建的一个具体事物,具体存在的,也就是特征和动作整合到一起
1.先举个例子:函数实现到类与对象实现
#学校类:
#特征:name,addr,type
#动作:考试,招生
##############第一步:函数方式实现
def school(name,addr,type):
def kao_shi(sch):
print('%s 学校正在考试' % school['name'])
def zhao_sheng(sch):
print('%s %s 正在招生' % (school['type'],school['name']))
sch = {
'name':name,
'addr':addr,
'type':type,
'kao_shi':kao_shi,
'zhao_sheng':zhao_sheng,
}
return sch
s1 = school('liantang','nanchang','公立')
print(s1) #返回sch
s1['zhao_sheng'](s1) #执行zhao_sheng函数
#################第二步:将sch打包进init函数
def school(name,addr,type):
def init(name,addr,type):
sch = {
'name':name,
'addr':addr,
'type':type,
'kao_shi':kao_shi,
'zhao_sheng':zhao_sheng,
}
return sch
def kao_shi(sch):
print('%s 学校正在考试' % school['name'])
def zhao_sheng(sch):
print('%s %s 正在招生' % (sch['type'],sch['name']))
return init(name,addr,type)
s1 = school('liantang','nanchang','公立')
print(s1)
s2 = school('清华','北京','公立')
print(s2)
print(s2['name'],s2['addr'],s2['type'])
s2['zhao_sheng'](s2)
#############第三步:定义一个类
class School:
def __init__(self,name,addr,type):
self.name = name
self.addr = addr
self.type = type
def kao_shi(self):
print('%s 学校正在考试' % self.name)
def zhao_sheng(self):
print('%s %s 正在招生' % (self.type,self.name))
#实例化对象
s1 = School('北大','北京','公立')
print(s1.name) #北大
print(s1.addr) #北京
print(s1.type) #公立
s1.kao_shi() #北大 学校正在考试
s1.zhao_sheng() #公立 北大 正在招生
#类调用函数属性
School.kao_shi(s1) #北大 学校正在考试
School.zhao_sheng(s1) #公立 北大 正在招生
2.类和对象的基本使用
class American:
'这是美国人的类'
dang = '共和党'
def sui_di_tu_tan():
print('朝着墙上就是一口痰')
def cha_dui(self):
print('插到了前面')
print(American.dang) #共和党
American.sui_di_tu_tan() #朝着墙上就是一口痰
American.cha_dui('hehe') #插到了前面
print(American.__dict__) #查看类的属性字典
print(American.__dict__['dang']) #共和党
American.__dict__['sui_di_tu_tan']() #朝着墙上就是一口痰
American.__dict__['cha_dui']('1') #插到了前面
################增加__init__初始化函数
class American:
'这是美国人的类'
dang = '共和党'
#def __init__(name,age,gender):
# dic={
# 'name':name,
# 'age':age,
# 'gender':gender
# }
# return dic
def __init__(self,name,age,gender):
self.mingzi=name #p1.mingzi=name
self.nianji=age #p1.nianji=age
self.xingbie=gender #p1.xingbie=gender
def sui_di_tu_tan(self):
print('%s 朝着墙上就是一口痰' % self.mingzi)
def cha_dui(self):
print('%s 插到了前面' % self.mingzi)
def eat_food(self,food):
print('%s 正在吃 %s' % (self.mingzi,food))
p1 = American('zhao',18,'male') #实例化 -->>__init__(self,name,age,gender)
#实例化的过程相当于p1 = American. __init__(p1,name,age,gender)
print(p1.__dict__) #{'mingzi': 'zhao', 'nianji': 18, 'xingbie': 'male'} 数据属性都封装给实例化对象p1
print(p1.__dict__['xingbie']) #male
print(p1.mingzi) #zhao
#print(p1.dang) #共和党 与函数作用域一样的过程
print(American.__dict__) #类的属性里面包含函数属性,实例化对象里面只有数据属性
American.sui_di_tu_tan(p1) #类调用函数属性:朝着墙上就是一口痰
American.cha_dui(p1) #类调用函数属性:zhao 插到了前面
#p1.sui_di_tu_tan() #报错
p1.cha_dui() #默认将p1当参数传入:zhao 插到了前面
p1.eat_food('饭')
#再来一个实例化对象
p2 = American('qian','18','female')
p2.eat_food('面')
#dir查看实例属性
print(dir(p2))
注意:
#对象是类实例而来,类实例化的结果称为一个实例或者称为一个对象
#实例化的过程其实就是执行__init__的过程,这个函数内部只是为实例本身即self设置一大堆数据,所以实例化只有数据属性
#.专门用来访问属性,本质操作的就是__dict__
#__init__方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值
#特殊的类属性
print(American.__name__) #类名:American
print(American.__doc__) #文档注释:这是美国人的类
print(American.__base__) #基类:<class 'object'>
print(American.__bases__) #该类的父类们,以元组形式(<class 'object'>,)
print(American.__module__) #模块名:__main__
print(American.__class__) #元类:生成类的类 默认为type <class 'type'>
3.类属型的增删改查
class ChinesePeople:
country = 'China'
def __init__(self,name):
self.name = name
def play_ball(self,ball):
print('%s 正在打 %s' % (self.name,ball))
def say_word(self,word):
print('%s 说 %s' % (self.name,word))
#查看类属性
print(ChinesePeople.country) #China
p3 = ChinesePeople('sun')
print(p3.country) #China
#修改属类性
ChinesePeople.country = 'CHINA'
print(ChinesePeople.country) #CHINA
#增加类属性
ChinesePeople.dang = '共产党'
print(ChinesePeople.dang) #共产党
print(p3.dang) #共产党
#删除类属性
del ChinesePeople.country
del ChinesePeople.dang
print(ChinesePeople.__dict__) #没有上面删除的两个数据属性
#print(ChinesePeople.country) #报错,因为没有这个属性了
#增加函数属性
def eat_food(self,food):
print('%s 正在吃 %s' % (self.name,food))
ChinesePeople.eat = eat_food
print(ChinesePeople.__dict__) #查找存在eat函数属性
p3.eat('饭') #sun 正在吃 饭
#修改函数属性
def test(self):
print('test')
ChinesePeople.play_ball = test
ChinesePeople.play_ball(p3) #test
p3.play_ball() #test
4.实例属性的增删改查
class Chinese:
country = 'China'
def __init__(self,name):
self.name = name
def play_ball(self,ball):
print('%s 正在打 %s' % (self.name,ball))
p1 = Chinese('li')
print(p1.__dict__) #{'name': 'li'}
#查看
print(p1.name)
p1.play_ball('ball') #li 正在打 ball
#增加
Chinese.gender = 'male'
print(Chinese.gender) #male
p1.age = 18
print(p1.age) #18
print(p1.__dict__) #{'name': 'li', 'age': 18}
#增加函数属性
def test(self):
print('测试而已')
p1.test = test
print(p1.__dict__) #{'name': 'li', 'age': 18, 'test': <function test at 0x0000020602751E18>}
print(Chinese.__dict__) #不包含test函数属性
p1.test(p1) #测试而已,原因在于p1实例化对象调用的是自己的函数,并不是类的,不会默认将自身传入
#修改
p1.age = 18
print(p1.__dict__) #{'name': 'li', 'age': 18, 'test': <function test at 0x000001DB984E1E18>}
print(p1.age) #18
#删除
del p1.age
print(p1.__dict__) #{'name': 'li', 'test': <function test at 0x000001B8956C1E18>}
5.内容补充
#####补充1:
#建议不要在__init__设置其他传入参数,例如input
class Chinese:
def __init__(self,name):
self.name = name
def play_ball(self,ball):
print('%s 正在打 %s' % (self.name,ball))
def shi_li_hua(ball):
name = input('-->>:')
p1 = Chinese(name)
p1.play_ball(ball)
shi_li_hua('football')
#####补充2:
#变量写在外面,在类里可以正常调用
country = 'china'
class Chinese:
def __init__(self,name):
self.name = name
print('-->>',country) #这里的country只是普通的变量
def play_ball(self,ball):
print('%s 正在打 %s' % (self.name,ball))
p1 = Chinese('tang') ##-->> china
#####补充3:
country = 'china'
class Chinese:
country = '中国'
def __init__(self,name):
self.name = name
print('-->>',country) #-->> china,只是不同变量,不会从类里面去查找,只会从外部变量查找
def play_ball(self,ball):
print('%s 正在打 %s' % (self.name,ball))
#类与对象调用属性从内部调用
p1 = Chinese('tang') #-->> china
print('实例',p1.country) #实例 中国
print(Chinese.__dict__) #类的属性字典
print(Chinese.country) #中国
######补充4:
class Chinese:
country = '中国'
def __init__(self,name):
self.name = name
def play_ball(self,ball):
print('%s 正在打 %s' % (self.name,ball))
p1 = Chinese('tang')
print(p1.country) #中国
p1.country = 'taiwan' #改变属性的值
print(p1.country) #taiwan
######补充5:
class Chinese:
country = 'china'
l = ['a','b']
def __init__(self,name):
self.name = name
def play_ball(self,ball):
print('%s 正在打 %s' % (self.name,ball))
p1 = Chinese('tang')
print(p1.l) #['a', 'b']
#p1.l = [1,2,3]
#print(Chinese.l) #['a', 'b']
#print(p1.l) #[1, 2, 3]
p1.l.append('c')
print(p1.__dict__) #{'name': 'tang'},c的增加只是类内部属性改变,与实例化对象无关
print(Chinese.l) #['a', 'b', 'c']
6.对象之间的简单交互
#盖伦
class Garen:
camp = 'Demacia'
def __init__(self,nickname,
aggressivity=58,
life_value=455,
money = 1001,
armor = 19):
self.nickname = nickname
self.aggressivity = aggressivity
self.life_value = life_value
self.money = money
self.armor = armor
def attack(self,enemy):
damage_value = self.aggressivity - enemy.armor
enemy.life_value -= damage_value
#瑞文
class Riven:
camp = 'Noxus'
def __init__(self,nickname,
aggressivity=54,
life_value=414,
money = 1000,
armor = 12
):
self.nickname = nickname
self.aggressivity = aggressivity
self.life_value = life_value
self.money = money
self.armor = armor
def attack(self,enemy):
damage_value = self.aggressivity - enemy.armor
enemy.life_value -= damage_value
class Sword:
def __init__(self,price=475,aggrev=9,life_value=100):
self.price = price
self.aggrev = aggrev
self.life_value = life_value
def update(self,obj):
obj.money -= self.price #减钱
obj.aggressivity += self.aggrev #加攻击
obj.life_value += self.life_value #加血量
def fire(self,obj): #装备主动技能,喷火
obj.life_value -= 1000
#测试交互
g1 = Garen('草丛伦')
r1 = Riven('瑞文文')
s1 = Sword()
print(r1.aggressivity,r1.life_value,r1.money) #54 414 1000
if r1.money > s1.price:
r1.s1 = s1
s1.update(r1)
print(r1.aggressivity,r1.life_value,r1.money) #63 514 525
print(g1.life_value) #455
r1.attack(g1) #普通攻击
print(g1.life_value) #411
r1.s1.fire(g1) #装备主动技能
print(g1.life_value) #-589