day6


属性
实例变量 每一个实例的变量
类变量 全部实例共享的变量,共享内存,13亿人都是实例的花 国际都是中国,只用存一份
私有属性 __var


方法
构造方法 __init__(self)初始化实例,执行的初始化动做
析构方法 实例销毁时释放时自动执行的方法(默认有析构函数,只不过什么都没干),写了的话至关于重构析构方法
私有方法html

 

 

 

 

 

面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就比如精心设计好一条流水线,是一种机械式的思惟方式。python

优势是:复杂度的问题流程化,进而简单化(一个复杂的问题,分红一个个小的步骤去实现,实现小的步骤将会很是简单)linux

缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线没法生产汽车,即使是能,也得是大改,改一个组件,牵一发而动全身。c++

应用场景:一旦完成基本不多改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。git

 

面向对象的程序设计:核心是对象二字,(要理解对象为什么物,必须把本身当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也能够创造出来。面向对象的程序设计比如如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题须要四我的:唐僧,沙和尚,猪八戒,孙悟空,每一个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并很差玩,因而如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。而后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取),对象是特征与技能的结合体,基于面向对象设计程序就比如在创造一个世界,你就是这个世界的上帝,存在的皆为对象,不存在的也能够创造出来,与面向过程机械式的思惟方式造成鲜明对比,面向对象更加注重对现实世界的模拟,是一种“上帝式”的思惟方式。shell

优势是:解决了程序的扩展性。对某一个对象单独修改,会马上反映到整个体系中,如对游戏中一我的物参数的特征和技能修改都很容易。数据库

缺点:编程

1. 编程的复杂度远高于面向过程,不了解面向对象而当即上手基于它设计程序,极容易出现过分设计的问题。一些扩展性要求低的场景使用面向对象会徒增编程难度,好比管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合。app

2. 没法向面向过程的程序设计流水线式的能够很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即使是上帝也没法准确地预测最终结果。因而咱们常常看到对战类游戏,新增一个游戏人物,在对战的过程当中极容易出现阴霸的技能,一刀砍死3我的,这种状况是没法准确预知的,只有对象之间交互才能准确地知道最终的结果。函数

应用场景:需求常常变化的软件,通常需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方

面向对象的程序设计并非所有。对于一个软件质量来讲,面向对象的程序设计只是用来解决扩展性。

选读:程序设计思想发展史

三 类与对象

类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象类似的特征与技能的结合体

那么问题来了,先有的一个个具体存在的对象(好比一个具体存在的人),仍是先有的人类这个概念,这个问题须要分两种状况去看

在现实世界中:先有对象,再有类

世界上确定是先出现各类各样的实际存在的物体,而后随着人类文明的发展,人类站在不一样的角度总结出了不一样的种类,如人类、动物类、植物类等概念

也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在

在程序中:务必保证先定义类,后产生对象

这与函数的使用是相似的,先定义函数,后调用函数,类也是同样的,在程序中须要先定义类,后调用类

不同的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象

 

按照上述步骤,咱们来定义一个类(咱们站在老男孩学校的角度去看,在座的各位都是学生)

 

 

 

#在程序中,务必保证:先定义(类),后使用(产生对象) PS: 1. 在程序中特征用变量标识,技能用函数标识 2. 于是类中最多见的无非是:变量和函数的定义 #程序中的类 class OldboyStudent: school='oldboy' def learn(self): print('is learning') def eat(self): print('is eating') def sleep(self): print('is sleeping') #注意: 1.类中能够有任意python代码,这些代码在类定义阶段便会执行 2.于是会产生新的名称空间,用来存放类的变量名与函数名,能够经过OldboyStudent.__dict__查看 3.对于经典类来讲咱们能够经过该字典操做类名称空间的名字(新式类有限制),但python为咱们提供专门的.语法 4.点是访问属性的语法,类中定义的名字,都是类的属性 #程序中类的用法 .:专门用来访问属性,本质操做的就是__dict__ OldboyStudent.school #等于经典类的操做OldboyStudent.__dict__['school'] OldboyStudent.school='Oldboy' #等于经典类的操做OldboyStudent.__dict__['school']='Oldboy' OldboyStudent.x=1 #等于经典类的操做OldboyStudent.__dict__['x']=1 del OldboyStudent.x #等于经典类的操做OldboyStudent.__dict__.pop('x') #程序中的对象 #调用类,或称为实例化,获得对象 s1=OldboyStudent() s2=OldboyStudent() s3=OldboyStudent() #如此,s一、s二、s3都同样了,而这三者除了类似的属性以外还各类不一样的属性,这就用到了__init__ #注意:该方法是在对象产生以后才会执行,只用来为对象进行初始化操做,能够有任意代码,但必定不能有返回值 class OldboyStudent: ...... def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex ...... s1=OldboyStudent('李坦克','',18) #先调用类产生空对象s1,而后调用OldboyStudent.__init__(s1,'李坦克','男',18) s2=OldboyStudent('王大炮','',38) s3=OldboyStudent('牛榴弹','',78) #程序中对象的用法 #执行__init__,s1.name='牛榴弹',很明显也会产生对象的名称空间 s2.__dict__ {'name': '王大炮', 'age': '', 'sex': 38} s2.name #s2.__dict__['name'] s2.name='王三炮' #s2.__dict__['name']='王三炮' s2.course='python' #s2.__dict__['course']='python' del s2.course #s2.__dict__.pop('course')


五 绑定到对象的方法的特殊之处

 
class OldboyStudent: school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def learn(self): print('%s is learning' %self.name) #新增self.name def eat(self): print('%s is eating' %self.name) def sleep(self): print('%s is sleeping' %self.name) s1=OldboyStudent('李坦克','',18) s2=OldboyStudent('王大炮','',38) s3=OldboyStudent('牛榴弹','',78)





#类变量的用途?你们公用的属性
#析构函数:在实例释放、销毁的时候执行的,一般用于作一些收尾工做,如关闭一些数据库链接,打开的临时文件
#封装
#继承
#多态
class Role(object):
n = 123 #类变量
n_list = []
name = '我是类name'#实例变量没有的话,会找类变量
def __init__(self,name,role,weapon,life_value=100,money=10000):#
#构造函数
#在实例化时作一些类的初始化的工做
self.name = name#r1.name=name赋给实例,实例变量,又叫静态属性。动态的传入,吧变量存到self至关于r1,不然函数中的name=name局部变量随函数结束就消失了存不下来
self.role = role#实例变量,做用域就是实例自己
self.weapon = weapon
self.__life_value = life_value
self.money = money

def shot(self):#类的方法,动态属性(也算一个属性,执行过程),功能,仍是在类中
print("%s 射击"%(self.name))

def got_shot(self):
self.__life_value -= 50
print("life_value:%s"%(self.__life_value))
def show_status(self):
print("name:%s life_value:%s"%(self.name,self.__life_value))

def buy_gun(self,gun_name):
print("%s buy a %s"%(self.name,gun_name))

def who_weapon(self):
print("%s has weapon %s"%(self.name,self.weapon))

def __del__(self):#传不了参数,在实例结束的时候自动执行的
print("%s 完全死了。。。"%(self.name))


print(Role.n)#类的变量存在类的内存中,不用实例化就能打印



Role('alex','police','ak47').shot()#用完了就会销毁的
Role('alex','police','ak47').shot()#新造的,和上一个不同,内存中的地址不一样
r1 = Role('alex','police','ak47')#Role('r1','alex','police','ak47')吧一个类变成一个具体对象的过程叫实例化 ,又叫初始化一个类,造了一个对象,赋值给一个变量,在内存中生成。开辟一块内存,存入属性
r1.name = 'ronghui'#在外面能够从新赋值给self.name

r1.bullet_prove = True#对于已经实例化的对象,能够加新的属性。至关于self.bullet_prove = bullet_prove

r1.buy_gun('ak47')#内部转成Role.buy_gun(r1) def buy_gun(self)必须有self,谁调用这个类,谁就是self

r1.n_list.append('from r1')
r2 = Role('jack','terrorist','B22') #生成一个角色

r2.shot()#Role.shot
r2.n_list.append('from r2')
print(Role.name,r1.name,r2.name,r1.bullet_prove)
print(r2.weapon)
#del r2.weapon #删除一个属性
r2.who_weapon()

r1.n = '改类变量'#在r1的内存里加了个 n='改类变量' 默认找r1中的n

print(r1.n)#实际上是在r1的内存中建立了个新的变量n

print(r2.n)#r2没有n,因此去类变量中找
Role.n = 'ABC'
print(r1.n,r2.n)#r1永远是本身的实例变量,r2没有实例变量n,因此只能去找类变量

print(r1.n_list,r2.n_list,Role.n_list)

r3 = Role('chenronghua','police','M4A1')
r3.got_shot()
r3.show_status()
 

类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可使用,但必须遵循函数的参数规则,有几个参数须要传几个参数

 
OldboyStudent.learn(s1) #李坦克 is learning OldboyStudent.learn(s2) #王大炮 is learning OldboyStudent.learn(s3) #牛榴弹 is learning
 

类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,并且是绑定到对象的,虽然全部对象指向的都是相同的功能,可是绑定到不一样的对象就是不一样的绑定方法

 

强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’自己当作第一个参数传给方法,即自动传值(方法__init__也是同样的道理)

 
s1.learn() #等同于OldboyStudent.learn(s1) s2.learn() #等同于OldboyStudent.learn(s2) s3.learn() #等同于OldboyStudent.learn(s3)
 

注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self能够是任意名字,可是约定俗成地写出self。

 

 

 

类即类型

 

  提示:python的class术语与c++有必定区别,与 Modula-3更像。

 

  python中一切皆为对象,且python3中类与类型是一个概念,类型就是类

 
复制代码
 
#类型dict就是类dict >>> list <class 'list'> #实例化的到3个对象l1,l2,l3 >>> l1=list() >>> l2=list() >>> l3=list() #三个对象都有绑定方法append,是相同的功能,但内存地址不一样 >>> l1.append <built-in method append of list object at 0x10b482b48> >>> l2.append <built-in method append of list object at 0x10b482b88> >>> l3.append <built-in method append of list object at 0x10b482bc8> #操做绑定方法l1.append(3),就是在往l1添加3,绝对不会将3添加到l2或l3 >>> l1.append(3) >>> l1 [3] >>> l2 [] >>> l3 [] #调用类list.append(l3,111)等同于l3.append(111) >>> list.append(l3,111) #l3.append(111) >>> l3 [111] 
 
 

六 对象之间的交互

 
class Garen:        #定义英雄盖伦的类,不一样的玩家能够用它实例出本身英雄; camp='Demacia' #全部玩家的英雄(盖伦)的阵营都是Demacia; def __init__(self,nickname,aggressivity=58,life_value=455): #英雄的初始攻击力58...; self.nickname=nickname #为本身的盖伦起个别名; self.aggressivity=aggressivity #英雄都有本身的攻击力; self.life_value=life_value #英雄都有本身的生命值; def attack(self,enemy): #普通攻击技能,enemy是敌人; enemy.life_value-=self.aggressivity #根据本身的攻击力,攻击敌人就减掉敌人的生命值。


class Riven: camp='Noxus' #全部玩家的英雄(锐雯)的阵营都是Noxus; def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻击力54; self.nickname=nickname #为本身的锐雯起个别名; self.aggressivity=aggressivity #英雄都有本身的攻击力; self.life_value=life_value #英雄都有本身的生命值; def attack(self,enemy): #普通攻击技能,enemy是敌人; enemy.life_value-=self.aggressivity #根据本身的攻击力,攻击敌人就减掉敌人的生命值。
 
 

实例出俩英雄

 
>>> g1=Garen('草丛伦') >>> r1=Riven('锐雯雯')
 
 
>>> g1.life_value
455
>>> r1.attack(g1) >>> g1.life_value 401 


class Garen:
camp='Demacia'
def __init__(self,nickname,
aggressivity=58,
life_value=455,
money=100,
armor=10):
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

def tell(self):
print('英雄属性 nickname:%s aggressivity:%s life_value:%s money:%s armor:%s'%(self.nickname, self.aggressivity,self.life_value,self.money,self.armor))

class Riven:
camp='netuox'
def __init__(self,nickname,
aggressivity=60,
life_value=300,
money=1000,
armor=20):
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

def tell(self):
print('英雄属性 nickname:%s aggressivity:%s life_value:%s money:%s armor:%s'%(self.nickname, self.aggressivity,self.life_value,self.money,self.armor))

class BlackCleaver:
def __init__(self,price=500,aggressivity=10000,life_value=10000):
self.price = price
self.aggressivity = aggressivity
self.life_value = life_value

def update(self,obj):
obj.money -= self.price
obj.aggressivity += self.aggressivity
obj.life_value += self.life_value
obj.tell()

def fire(self,obj): #这是该装备的主动技能,喷火,烧死对方
obj.life_value-=1000 #假设火烧的攻击力是1000

g1 = Garen('草丛伦')
r1 = Riven('瑞文文')
b1 = BlackCleaver()

r1.b1=b1
r1.b1.fire(g1)
print(g1.life_value)

if r1.money > b1.price:
b1.update(r1)

r1.attack(g1)
print(g1.life_value)
相关文章
相关标签/搜索