#解决同一类问题,使用面向对象的思想。类是制造对象的模具,类是抽象的,我们能知道它有哪些属性(name,age,saraly),但不知道具体的属性值。 #看下面代码:类Penson制造了实例化对象ret,它有具体的属性值。 # 一、 class Penson: #类名首字母大写。这里Penson或Penson()都可以。 job = 'programmer' #类属性(静态属性) def __init__(self,*args): #这四行代码是属性,__init__是初始化方法,self是空字典,*args是必须传参数的元组。 self.name = args[0] #self增加属性(添加键值对)。 self.age = args[1] self.saraly = args[2] #self返回给Penson,而ret = Penson,所以ret = Penson = self。 def func(self,n): #这两行代码是方法。 print('{},{}岁,年收入{}万,每天学习最少{}个小时'.format(self.name,self.age,self.saraly,n)) #类名.属性名 调用属性:self.name ret = Penson('xiaoming',30,80) #此操作是实例化,ret是实例化对象。 ret.func(2) #调用方法。对象名.方法名(参数)相当于类名.方法名(实例化对象,参数):Penson.func(ret,2) 。结果是:xiaoming,30岁,年收入80万,每天学习最少2个小时 ret = Penson('tom',20,10) ret.func(3) #结果是:tom,20岁,年收入10万,每天学习最少3个小时 #面向对象的好处:方便增加人物、代码精简、方便修改。 print(Penson.job) #查看类属性 print(ret.job) #查看类属性 print(ret.name) #查看属性 print(ret.age) #查看属性 print(ret.saraly)#查看属性 print(ret.__dict__) #查看所有属性,结果是{'name': 'tom', 'age': 20, 'saraly': 10},除了类属性:job = 'programmer' ret.name = 'marry' #修改属性 print(ret.name) #marry # 二、验证self是字典、ret = self: class Penson: def __init__(self,name): print(self.__dict__) #结果是{} self.name = name print(self.__dict__) #结果是{'name': 'xiaoming'},证明self是字典。 print(id(self.__dict__)) #8376656 def func(self,n): print('{},32岁,年收入100万,每天学习最少{}个小时'.format(self.name,n)) ret = Penson('xiaoming') ret.func(3) print(id(ret.__dict__)) #8376656,ret.__dict__和self.__dict__地址一样,证明ret = self。 # 三、练习:传入不同的半径,计算面积和周长: from math import pi class Math: def __init__(self,r): self.r = r def areas(self): print('面积是{}'.format(pi*self.r**2)) def perimeter(self): print('周长是%s,%s'%(self.r*2*pi,self.r)) ret = Math(2) ret.areas() ret.perimeter() ret = Math(1) ret.areas() ret.perimeter() # 四、命名空间:类的命名空间讲述的是对象的类属性修改或重新赋值之后,对类属性的影响。 #1.不可变数据类型:重新赋值是单独的。 class Penson: job = 'programmer' #'programmer'是字符串,是不可变数据类型。类属性(静态属性、静态变量)存在于类的命名空间当中。 def __init__(self,*args): self.name = args[0] self.age = args[1] self.saraly = args[2] def func(self,n): print('{},{}岁,年收入{}万,每天学习最少{}个小时'.format(self.name,self.age,self.saraly,n)) ret = Penson('xiaoming',30,80) ret1 = Penson('tom',30,80) print(Penson.job) #programmer print(ret.job) #programmer print(ret1.job) #programmer ret1.job = 'teacher' #字符串无法修改,此操作是重新赋值,相当于增加新的类属性(新对象) print(Penson.job) #programmer print(ret.job) #programmer print(ret1.job) #teacher del ret1.job #删除ret1的类属性,它的类属性变回‘programmer’ print(Penson.job) #programmer print(ret.job) #programmer print(ret1.job) #programmer #2.可变数据类型:修改是共享的,重新赋值是单独的。 #2.1 修改是共享的: class Penson: job = ['programmer'] #列表是可变数据类型。 def __init__(self,*args): self.name = args[0] self.age = args[1] self.saraly = args[2] def func(self,n): print('{},{}岁,年收入{}万,每天学习最少{}个小时'.format(self.name,self.age,self.saraly,n)) ret = Penson('xiaoming',30,80) ret1 = Penson('tom',30,80) print(Penson.job) #['programmer'] print(ret.job) #['programmer'] print(ret1.job) #['programmer'] ret1.job[0] = 'teacher' #修改ret1的类属性,没有增加新属性。 print(Penson.job) #['teacher'] print(ret.job) #['teacher'] print(ret1.job) #['teacher'] del ret1.job[0] #删除ret1的类属性,Penson、ret、ret1的类属性变成空列表[] print(Penson.job) #[] print(ret.job) #[] print(ret1.job) #[] #2.2 重新赋值是单独的: ret = Penson('xiaoming',30,80) ret1 = Penson('tom',30,80) print(Penson.job) #['programmer'] print(ret.job) #['programmer'] print(ret1.job) #['programmer'] ret1.job = ['teacher'] #重新赋值,相当于增加新属性,新属性是ret1自己的,没共享给Penson和ret. print(Penson.job) #['programmer'] print(ret.job) #['programmer'] print(ret1.job) #['teacher'] del ret1.job #删除ret1的类属性,ret1的类属性变回['programmer'] print(Penson.job) #['programmer'] print(ret.job) #['programmer'] print(ret1.job) #['programmer'] #3.1 练习: class Family: money = 0 mother = Family() father = Family() mother.money += 1000 father.money += 1000 print(mother.money) #1000,妈妈的钱进了自己的账。因为mother在自己的命名空间当中创建了新的属性。 print(father.money) #1000,爸爸的钱也进了自己的账。 print(Family.money) #家庭进账是0,因为mother、father、Penson是不同的命名空间。参考下面代码: class Family: money = 0 def work(self): Family.money += 1000 #类属性(静态属性、静态变量)存在于类的命名空间当中 mother = Family() father = Family() mother.work() father.work() print(mother.money) #2000 print(father.money) #2000 print(Family.money) #2000 #3.2 练习:创建一个类,每实例化一个对象就计数,最后所有对象都共享这个数据。 class Penson: count = 0 def __init__(self): Penson.count += 1 #类属性(静态属性、静态变量)存在于类的命名空间当中 func1 = Penson() #一调用Penson就启动__init__方法。 func2 = Penson() print(func1.count) #2 print(func2.count) #2 func3 = Penson() print(func1.count) #3 print(func2.count) #3 print(func3.count) #3 #五.在类的外面进行属性的增删改查: class Penson: a = 100000 def __init__(self): self.money = 0 poor = Penson() print(poor.money) #0 poor.rmb = 8000000 #增加新属性:对象增加新属性,Penson没有这个属性。 print(poor.rmb) #8000000 ,查看属性 print(poor.__dict__) #{'money': 0, 'rmb': 8000000},查看除了类属性之外的所有属性,类属性是a = 100000。 del poor.money #删除属性 print(poor.__dict__) #{'rmb': 8000000} poor.rmb = 10000000 # 修改属性 print(poor.__dict__) #{'rmb': 10000000} print(poor.a) #100000 #六:练习:人狗大战: # 1.面向对象的交互(Penson类里面有Dog类的对象,Dog类里面有Penson类的对象) # 2.组合:对象属性是另外一个类的对象。 class Penson: def __init__(self,name,aggr,hp): #姓名、攻击力、血 self.name = name self.aggr = aggr self.hp = hp self.money = 0 def attack(self,dog): #定义攻击技能。 dog.hp -= self.aggr #人攻击狗,狗掉血。狗掉的血等于人的攻击力。另外一个类的对象属性dog.hp可以在本类当中修改。 def get_weapon(self,weapon): #定义得到装备技能。调用此技能,就可以得到装备。 if self.money > weapon.money: #得到装备之前,要判断人的钱是否多于装备的钱 self.money -= weapon.money self.weapon = weapon #增加装备属性(得到装备)。组合:对象属性是另外一个类的对象。 else: print('余额不足,请先充值') class Dog: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp def bite(self,penson): penson.hp -= self.aggr #狗咬人,人掉血。 class Weapon: def __init__(self,name,aggr,count,money): self.name = name self.aggr = aggr self.count = count #装备可用的攻击次数 self.money = money def att(self,dog): if self.count >0: #攻击狗之前,要先判断装备的攻击次数是否大于0 dog.hp -= self.aggr self.count -= 1 else: print('装备可用的攻击次数为0') alex = Penson('alex',20,10) alex.money = 1000 #充值 jin = Dog('jin',200,50) w = Weapon('打狗棒',10,3,900) alex.attack(jin) print(jin.hp) #50-20=30 alex.get_weapon(w) #调用装备,得到装备。把w传给Penson类里面def get_weapon(self,weapon)这句代码的weapon. alex.weapon.att(jin) #使用装备攻击狗。因为在Penson类里面,self.weapon = weapon,对象属性是另外一个类的对象,所以alex.weapon.att(jin)相当于w.att(jin),调用Weapon类的att技能。 #因为w.att(jin)装备攻击狗,不符合逻辑,而人调用装备,得到装备,使用装备攻击狗才是符合逻辑的,所以要想办法把w传给人,那么,人增加对象属性就可以了:self.weapon = w。 print(jin.hp) #30-10=20 jin.bite(alex) print(alex.hp) #人调用装备--得到装备--利用装备的技能攻击狗: def get_weapon(self,weapon): #定义调用装备技能 self.weapon = weapon # 得到装备 alex.get_weapon(w) #人调用装备--装备传入给人 alex.weapon.att(jin) #利用装备的技能攻击狗 #七.组合:对象属性是另外一个类的对象,这样就可以调用另外一个类的对象方法了。反过来,对象方法可以被另外一个类的对象属性引用。 from math import pi class Math: def __init__(self,r): self.r = r def areas(self): return pi*self.r**2 def perimeter(self): return 2*pi*self.r class Circle: def __init__(self,outside_r,inside_r): self.outside_c = Math(outside_r) #组合:对象属性是另外一个类的对象。 self.inside_c = Math(inside_r) def areas(self): return self.outside_c.areas()-self.inside_c.areas() #调用另外一个类的对象方法 c = Circle(20,10) print(c.areas())