发布时间:2018-04-11 16:59:09编辑:Run阅读(3915)
对象之间的交互
现在有个游戏人与狗,人定义一个类,狗定义一个类,如何让两个类之间互相交互起来,让这个游戏变得更加有意思,代码如下
#!/usr/bin/env python # coding: utf-8 __author__ = 'www.py3study.com' class Person: # 定义一个人类 role = 'person' # 人的角色属性都是人 def __init__(self, name, sex, hp, ad): self.name = name # 每个角色都有自己的昵称 self.sex = sex # 性别 self.hp = hp # 血量 self.ad = ad # 攻击力 def attack(self, dog): # 人可以攻击狗,这里的dog也是一个对象 # 人攻击狗,那么狗的生命值会根据人的攻击力而下降 dog.hp -= self.ad print('{}攻击了{},{}掉了{}点血'.format(self.name,dog.name,dog.name,self.ad)) class Dog: # 定义狗类 role = 'dog' def __init__(self, name, breed, hp, ad): self.name = name # 每一只狗都有自己的昵称 self.breed = breed # 狗品种 self.hp = hp # 狗的血量 self.ad = ad # 狗的攻击力 def bite(self, people): # 狗可以咬人,这里的狗也是一个对象 # 狗咬人,那么人的生命值就会根据狗的攻击力下降 people.hp -= self.ad print('{}攻击了{},{}掉了{}点血'.format(self.name, people.name, people.name, self.ad)) boss_sam = Person('Sam', '男', 100, 100) # 实例化一个角色boss_sam ha2 = Dog('二愣子', '哈士奇', 50, 50) # 实例化一个角色ha2 boss_sam.attack(ha2) # boss_sam攻击了ha2, print(ha2.hp) # 打印ha2的血量 ha2.bite(boss_sam) # ha2咬了boss_sam print(boss_sam.hp) # 打印boss_sam的血量
执行结果
Sam攻击了二愣子,二愣子掉了100点血
-50
二愣子攻击了Sam,Sam掉了50点血
50
例2
from math import pi class Circle: # Circle类名 ''' 定义了一个圆形类; 提供计算面积(area)和周长(perimeter)的方法 圆的面积为:圆周率×2×半径 圆的周长为:圆周率×半径的平方 ''' def __init__(self, radius): # radius半径 self.radius = radius def perimeter(self): return pi * self.radius * 2 def area(self): return pi * self.radius ** 2 circle = Circle(10) # 实例化一个圆,传入半径值10 areal = circle.area() # 计算圆面积 perl = circle.perimeter() # 计算圆周长 print('半径为10的圆面积是:{},周长是{}'.format(areal,perl))
执行结果
半径为10的圆面积是:314.1592653589793,周长是62.83185307179586
例3,上面题目的升级版,计算半径分别是1,3,5,7,9圆的面积与周长
from math import pi class Circle: # Circle类名 ''' 定义了一个圆形类; 提供计算面积(area)和周长(perimeter)的方法 圆的面积为:圆周率×2×半径 圆的周长为:圆周率×半径的平方 ''' def __init__(self, radius): # radius半径 self.radius = radius def perimeter(self): return pi * self.radius * 2 def area(self): return pi * self.radius ** 2 for i in range(1,10,2): # 步长为2,i的值为1,3,5,7,9 cl = Circle(i) # 实例化参入变量i,i为半径1,3,5,7,9 print(cl.perimeter()) # 打印圆周长 print(cl.area()) # 打印圆面积
执行结果
6.283185307179586
3.141592653589793
18.84955592153876
28.274333882308138
31.41592653589793
78.53981633974483
43.982297150257104
153.93804002589985
56.548667764616276
254.46900494077323
类命名空间与对象、实例的命名空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这里名字称为类的属性
而类有两种属性:静态属性和动态属性
1 静态属性就是直接在类中定义的变量
2 动态属性就是定义在类中的方法
例1,错误的示例
class Person: role = 'person' def __init__(self, name, sex, hp, ad): self.name = name self.sex = sex self.hp = hp self.ad = ad self.attack = 'hahaha哦了' def attack(self): print('{}发起了一次攻击'.format(self.name)) sam = Person('sam_sb', '不详', 9999, 9999) sam.attack() print(sam.__dict__)
执行报错
TypeError: 'str' object is not callable
为什么呢?因为attack变成字符串了,它不能执行
改成
print(sam.attack)
print(sam.__dict__)
执行结果
hahaha哦了
{'sex': '不详', 'ad': 9999, 'name': '高富帅', 'hp': 9999, 'attack': 'hahaha哦了'}
类的数据属性是共享给所有对象的,根据上面的例子,在添加一个实例对象
class Person: role = 'person' def __init__(self, name, sex, hp, ad): self.name = name self.sex = sex self.hp = hp self.ad = ad self.attack = 'hahaha哦了' def attack(self): print('{}发起了一次攻击'.format(self.name)) sam = Person('白人', '不详', 9999, 9999) tom = Person('黑人', '不详', 1, 1) print(sam.role) print(tom.role)
执行结果
person
person
修改类变量
class Person: role = 'person' def __init__(self, name, sex, hp, ad): self.name = name self.sex = sex self.hp = hp self.ad = ad self.attack = 'hahaha哦了' def attack(self): print('{}发起了一次攻击'.format(self.name)) sam = Person('白人', '不详', 9999, 9999) tom = Person('黑人', '不详', 1, 1) sam.role = 'hahaha' print(sam.role) print(tom.role)
执行结果
hahaha
person
但凡是对象操作类属性,它是没有权利的,它只能存储在自己内存空间里面,类可以没有init方法
模拟人生游戏,模拟一家人赚钱的游戏
例,错误示例
class Person: money = 0 def __init__(self, name): self.name = name def work(self): print(self.name, '工作,赚了1000块') self.money += 1000 father = Person('father') mother = Person('motner') father.work() mother.work() print(Person.money)
执行结果
father 工作,赚了1000块
motner 工作,赚了1000块
0
但是钱没有涨?为什么?
每一次重新赋值,相当于一个新的变量
加法运算时,拿了类变量,对于类变量,mong=0,它还是0
怎么解决这个问题呢?
例2
class Person: money = 0 def __init__(self, name): self.name = name def work(self): print(self.name, '工作,赚了1000块') Person.money += 1000 father = Person('father') mother = Person('motner') father.work() mother.work() print(Person.money)
执行结果
father 工作,赚了1000块
motner 工作,赚了1000块
2000
对于静态属性的修改,应该使用类名直接修改,就不会出现不一致的情况,因为类属性是共享的
练习题,写一个类,完成一个功能,可以统计这个类有几个对象
class Foo: count = 0 def __init__(self): Foo.count += 1 f1 = Foo() #实例化一个对象 f2 = Foo() #实例化一个对象 f3 = Foo() #实例化一个对象 print(Foo.count)
执行结果
3
例2:可变数据类型当做类静态属性(有坑!)
class Person: money = [0] # money为一个列表 def __init__(self, name): self.name = name def work(self): print(self.name, '工作,赚了1000块') self.money[0] += 1000 father = Person('father') mother = Person('motner') father.work() mother.work() print(Person.money)
执行结果
father 工作,赚了1000块
motner 工作,赚了1000块
[2000]
为什么是2000?
例3:
class Person: money = [0] # money为一个列表 def __init__(self, name): self.name = name def work(self): print(self.name, '工作,赚了1000块') self.money = [Person.money[0] + 1000] father = Person('father') mother = Person('motner') father.work() mother.work() print(Person.money)
执行结果
father 工作,赚了1000块
motner 工作,赚了1000块
[0]
为什么结果是0?
不管是类里面还是类外面,统一使用:类名.静态变量名
47745
46235
37110
34627
29229
25886
24745
19863
19417
17908
5716°
6315°
5835°
5888°
6984°
5829°
5846°
6361°
6316°
7673°