第二十二天面向对象的:
1。用面向过程来写人狗大战游戏:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def Dog (name,blood,aggr,kind):#首先定义一个狗属性的函数 dog={ 'name':name,#狗具有的属性 'blood':blood, 'aggr':aggr, 'kind':kind } def bite(person): #狗进行攻击时,有什么现象: person['blood']-=dog['aggr'] #狗咬人,人掉血 print('%s被咬了,掉了%s的血'%(person['name'],dog['aggr'])) dog['bite']=bite return dog def Person (name,blood,aggr,kind):#首先定义一个人属性的函数 person={ 'name':name,#人具有的属性 'blood':blood, 'aggr':aggr, 'kind':kind } def attack(dog):#人进行攻击时,有什么现象: dog['blood']-=person['aggr'] #人打狗,狗掉血 print('s被打了,掉了%s的血'%(dog['name'],person['aggr'])) person['attack']=attack return person alex=Dog('alex',100,2,'teer') small=Person('small',122,3,'不祥') print(alex['bite'](small))
通过此程序可以引入面向对象的函数,所谓面向对象就是指的类:类是抽象的,但是我们能知道它具有什么属性,有什么方法,但是不能知道属性的具体值。
程序中的jin、alex就是对象,有具体的对象、有具体的值,属性和技能都是根据类型进行规范:
2.面向过程和面向对象的对比:
面向过程核心就是流水线式的,过程就是解决问题的核心,面向过程的设计就像是精心设计好的一条流水线,考虑周全什么问题用什么函数进行处理
优点是极大降低了写程序的复杂程度,只需要按照顺序一次进行下去就可以,堆叠代码就可以
· 缺点是一套流水线式的代码就只能用来解决一个问题,代码一修改全部都要改变
面向对象的核心就是对象:要记住一切皆对象,不存在的东西也是可以创造出来的,比如:面向对象来设计西游记,首先要解决的是要把经书传给东土大唐,如来想要解决这个问题就要四个人:唐僧,沙和尚、猪八戒、孙悟空,每个人都有各自的特征和技能(这些都是对象的概念特征和技能是对象的属性和方法)然而这还不是特别有趣,于是如来又给他们安排了一些妖魔鬼怪,为了防止在取经的路上被杀死,有安排一些神仙进行保护,这些也都是对象,然后开始取经,师徒4人与妖魔鬼怪神仙进行回想缠斗最后取得真经。
优点:解决了程序的扩展性问题,对于某一个对象的单独修改,会立刻反映到整个系统当中去,如对游戏中的一个人物特征的特和技能进行修改都很容易
缺点:可控性差,无法面向过程的流水画设计,可以精准的预测到问题的处理流程和结果。
1类:
1·1初始类:python中一些的数据类型都是类:可以这样理解数据类型中都带类字,它们定义的每个变量都是对象:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
print(type(list),type(dict)) #为类 lis1=[1,34,5]#对象 print(type(lis1)) 结果为 <class 'type'> <class 'type'> <class 'list'>
1.2类的定义:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class 类名:#类名的首写字母一般要大些 pass
1.3类的第一个函数:(把上面的人狗大战中人的函数改成面向对象的)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Person:#一般不需要括号 country='china'#创造了一个类的属性,属于静态方法,只能查看,而且只要是这个类就一定有这个属性 def __init__(self,*args):#初始化方法,一般定义类时把他放在开头,self是必须要传递的参数,相当于一个字典 self.name=args[0] #往self字典中添加对象的属性 self.blood=args[1] self.aggr=args[2] self.sex=args[3]#当程序执行完以后会默认进行return返回self字典 def walk(self,n): #类中的方法,一般情况下必须传self参数,且必须写在第一位 print('%s走走走,走了%s步'%(self.name,n)) print(Person.country)# 可以通过类名查看类中的静态属性,不需要实例化就能看, alex=Person('苟胜二',100,1,'不想')#类名可以实例化对象,alex就是对象 print(alex.__dict__)#查看对象中的所有属性 print(alex)#返回一个对象 print(alex.name)#也可以分别查看对象中的每一个属性 alex.walk(5)#调用类里面的方法#也可以使用下面这种方法 Person.walk(alex,7) 结果为 china {'name': '苟胜二', 'blood': 100, 'aggr': 1, 'sex': '不想'} <__main__.Person object at 0x000001D4D65CB0B8> 苟胜二 苟胜二走走走,走了5步 苟胜二走走走,走了7步
1.4怎么判别对象alex就是返回的__init中的self(使用id查看内存地址)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Person:#一般不需要括号 country='china'#创造了一个类的属性,属于静态方法,只能查看,而且只要是这个类就一定有这个属性 def __init__(self,*args):#初始化方法,一般定义类时把他放在开头,self是必须要传递的参数,相当于一个字典 self.name=args[0] #往self字典中添加对象的属性 self.blood=args[1] self.aggr=args[2] self.sex=args[3]#当程序执行完以后会默认进行return返回self字典 print(id(self)) def walk(self,n): #类中的方法,一般情况下必须传self参数,且必须写在第一位 print('%s走走走,走了%s步'%(self.name,n)) print(Person.country)# 可以通过类名查看类中的静态属性,不需要实例化就能看, alex=Person('苟胜二',100,1,'不想')#类名可以实例化对象,alex就是对象 print(id(alex)) 结果为 china 2843156787608 2843156787608
1.5对对象里面的值进行修改的方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Person:#一般不需要括号 country='china'#创造了一个类的属性,属于静态方法,只能查看,而且只要是这个类就一定有这个属性 def __init__(self,*args):#初始化方法,一般定义类时把他放在开头,self是必须要传递的参数,相当于一个字典 self.name=args[0] #往self字典中添加对象的属性 self.blood=args[1] self.aggr=args[2] self.sex=args[3]#当程序执行完以后会默认进行return返回self字典 def walk(self,n): #类中的方法,一般情况下必须传self参数,且必须写在第一位 print('%s走走走,走了%s步'%(self.name,n)) print(Person.country)# 可以通过类名查看类中的静态属性,不需要实例化就能看, alex=Person('苟胜二',100,1,'不想')#类名可以实例化对象,alex就是对象 print(alex.__dict__)#查看对象中的所有属性 print(alex.name) alex.name='sb' #第一种方法进行对象值得修改 print(alex.name) alex.__dict__['name']='kjdfkj'#第二种方法进行对象值得修改 print(alex.name) 结果为 china {'name': '苟胜二', 'blood': 100, 'aggr': 1, 'sex': '不想'} 苟胜二 sb kjdfkj
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Person:#一般不需要括号 country='china'#创造了一个类的属性,属于静态方法,只能查看,而且只要是这个类就一定有这个属性 def __init__(self,*args):#初始化方法,一般定义类时把他放在开头,self是必须要传递的参数,相当于一个字典 self.name=args[0] #往self字典中添加对象的属性 self.blood=args[1] self.aggr=args[2] self.sex=args[3]#当程序执行完以后会默认进行return返回self字典 def walk(self,n): #类中的方法,一般情况下必须传self参数,且必须写在第一位 print('%s走走走,走了%s步'%(self.name,n)) print(Person.country)# 可以通过类名查看类中的静态属性,不需要实例化就能看, Person.__init__['country']='jfdkjf' #不支持这种修改类中静态的变量方式 结果为 china Traceback (most recent call last): File "D:/python练习程序/第二十二天/类和对象.py", line 101, in <module> Person.__init__['country']='jfdkjf' #不支持这种修改类中静态的变量方式 TypeError: 'function' object does not support item assignment
1.6对象=类名()
过程:
类名() 首先会创造出一个对象,创建一个self的变量
· 调用init方法,类名括号里的参数会被这里接受
· 执行init方法
返回self
对象能做的事:
能查看属性、对属性进行修改
调用方法
· __dict__对于对象的增删改查操作可以通过字典的操作语法进行
1.7类名能做的操作;
将类进行实例化,
调用方法,只不过要自己传递self参数
调用类中的属性,也就是只能调用静态属性
__dict__对于类中的名字只能进行查看,不能进行操作
2.类的练习题:
2.1
# 练习一:在终端输出如下信息
#
# 小明,10岁,男,上山去砍柴
# 小明,10岁,男,开车去东北
# 小明,10岁,男,最爱大保健
# 老李,90岁,男,上山去砍柴
# 老李,90岁,男,开车去东北
# 老李,90岁,男,最爱大保健
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Information: #对于非常明显处理一类事物,这些实物具有相似的属性和功能 def __init__(self,*args):#当有几个函数,需要反反复复传入相同的参数事可以考虑面向对象 self.name=args[0]#这些对象都是对象的属性 self.age=args[1] self.sex=args[2] def cut_tree(self): print('%s,%s,%s,上山去砍柴'%(self.name,self.age,self.sex)) def drive(self): print('%s,%s,%s,开车去东北'%(self.name,self.age,self.sex)) def love(self): print('%s,%s,%s,最爱大保健'%(self.name,self.age,self.sex)) 小明=Information('小明',10,'男') 老李=Information('老李',90,'男') 小明.cut_tree() 小明.drive() 小明.love() 老李.cut_tree() 老李.drive() 老李.love()
2.2# circle 属性 半径 ,两个方法:求周长和面积
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from math import pi class Circle: def __init__(self,*args): self.r=args[0] def permeters(self): return 2*pi*self.r def area(self): return pi*(self.r**2)#要用括号保证优先级 c1=Circle(4) print(c1.area()) print(c1.permeters()) 结果为 50.26548245743669 25.132741228718345
进行优化把小数点保留两位
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from math import pi class Circle: def __init__(self,*args): self.r=args[0] def permeters(self): return round(2*pi*self.r,2) def area(self): return round(pi*(self.r**2),2)#要用括号保证优先级 c1=Circle(4) print(c1.area()) print(c1.permeters()) 结果为 50.27 25.13
2.3把最先写的人狗大战程序改成面向对象的程序:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Dog: def __init__(self,*args): self.name=args[0] self.blood=args[1] self.aggr=args[2] self.sex=args[3] def bite(self,person): person.blood-=self.aggr class Person: def __init__(self,*args): self.name=args[0] self.blood=args[1] self.aggr=args[2] self.sex=args[3] def bite(self,dog): dog.blood-=self.aggr if dog.blood<=0: print('%s打了%s,%s被打死了,扑街了。。。。'%(self.name,dog.name,dog.name)) else: print('%s打了%s,掉血掉了%s'%(self.name,dog.name,self.aggr)) jin=Dog('金老板',103,20,'teedy') print(jin.__dict__) alex=Person('alex',100,32,'不想') alex.bite(jin) alex.bite(jin) alex.bite(jin) alex.bite(jin) 结果为 {'name': '金老板', 'blood': 103, 'aggr': 20, 'sex': 'teedy'} alex打了金老板,掉血掉了32 alex打了金老板,掉血掉了32 alex打了金老板,掉血掉了32 alex打了金老板,金老板被打死了,扑街了。。。。