python day 18 面向对象之交互,命名空间作用域,组合

对象的相关知识

回到咱们的人狗大战:现在我们需要对我们的类做出一点点改变人类除了可以走路之外,还应该具备一些攻击技能。

 1 class Person:  # 定义一个人类
 2     role = 'person'  # 人的角色属性都是人
 3 
 4     def __init__(self, name, aggressivity, life_value):
 5         self.name = name  # 每一个角色都有自己的昵称;
 6         self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;
 7         self.life_value = life_value  # 每一个角色都有自己的生命值;
 8 
 9     def attack(self,dog):  
10         # 人可以攻击狗,这里的狗也是一个对象。
11         # 人攻击狗,那么狗的生命值就会根据人的攻击力而下降
12         dog.life_value -= self.aggressivit
View Code

对象是关于类而实际存在的一个例子,即实例

对象/实例只有一种作用:属性引用

1 egg = Person('egon',10,1000)
2 print(egg.name)
3 print(egg.aggressivity)
4 print(egg.life_value)
View Code

当然了,你也可以引用一个方法,因为方法也是一个属性,只不过是一个类似函数的属性,我们也管它叫动态属性。
引用动态属性并不是执行这个方法,要想调用方法和调用函数是一样的,都需要在后面加上括号

1 print(egg.attack)
View Code

我知道在类里说,你可能还有好多地方不能理解。那我们就用函数来解释一下这个类呀,对象呀到底是个啥,你偷偷的用这个理解就好了,不要告诉别人

 1 def Person(*args,**kwargs):
 2     self = {}
 3     def attack(self,dog):
 4         dog['life_value'] -= self['aggressivity']
 5 
 6     def __init__(name,aggressivity,life_value):
 7         self['name'] = name
 8         self['aggressivity'] = aggressivity
 9         self['life_value'] = life_value
10         self['attack'] = attack
11 
12     __init__(*args,**kwargs)
13     return self
14 
15 egg = Person('egon',78,10)
16 print(egg['name'])
帮你了解面向对象

面向对象小结——定义及调用的固定模式

 1 class 类名:
 2     def __init__(self,参数1,参数2):
 3         self.对象的属性1 = 参数1
 4         self.对象的属性2 = 参数2
 5 
 6     def 方法名(self):pass
 7 
 8     def 方法名2(self):pass
 9 
10 对象名 = 类名(1,2)  #对象就是实例,代表一个具体的东西
11                   #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法
12                   #括号里传参数,参数不需要传self,其他与init中的形参一一对应
13                   #结果返回一个对象
14 对象名.对象的属性1   #查看对象的属性,直接用 对象名.属性名 即可
15 对象名.方法名()     #调用类中的方法,直接用 对象名.方法名() 即可
小结
1 练习一:在终端输出如下信息
2 
3 小明,10岁,男,上山去砍柴
4 小明,10岁,男,开车去东北
5 小明,10岁,男,最爱大保健
6 老李,90岁,男,上山去砍柴
7 老李,90岁,男,开车去东北
8 老李,90岁,男,最爱大保健
9 老张…
练一练

对象之间的交互

现在我们已经有一个人类了,通过给人类一些具体的属性我们就可以拿到一个实实在在的人。
现在我们要再创建一个狗类,狗就不能打人了,只能咬人,所以我们给狗一个bite方法。
有了狗类,我们还要实例化一只实实在在的狗出来。
然后人和狗就可以打架了。现在我们就来让他们打一架吧!

创建一个狗类

 1 class Dog:  # 定义一个狗类
 2     role = 'dog'  # 狗的角色属性都是狗
 3 
 4     def __init__(self, name, breed, aggressivity, life_value):
 5         self.name = name  # 每一只狗都有自己的昵称;
 6         self.breed = breed  # 每一只狗都有自己的品种;
 7         self.aggressivity = aggressivity  # 每一只狗都有自己的攻击力;
 8         self.life_value = life_value  # 每一只狗都有自己的生命值;
 9 
10     def bite(self,people):
11         # 狗可以咬人,这里的狗也是一个对象。
12         # 狗咬人,那么人的生命值就会根据狗的攻击力而下降
13      dog.life_value -= self.aggressivit
View Code

实例化一只实实在在的二哈

1 ha2 = Dog('二愣子','哈士奇',10,1000)  #创造了一只实实在在的狗ha2
View Code

交互 egon打ha2一下

1 print(ha2.life_value)         #看看ha2的生命值
2 egg.attack(ha2)               #egg打了ha2一下
3 print(ha2.life_value)         #ha2掉了10点血
View Code

完整的代码

 1 class Person:  # 定义一个人类
 2     role = 'person'  # 人的角色属性都是人
 3 
 4     def __init__(self, name, aggressivity, life_value):
 5         self.name = name  # 每一个角色都有自己的昵称;
 6         self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;
 7         self.life_value = life_value  # 每一个角色都有自己的生命值;
 8 
 9     def attack(self,dog):
10         # 人可以攻击狗,这里的狗也是一个对象。
11         # 人攻击狗,那么狗的生命值就会根据人的攻击力而下降
12         dog.life_value -= self.aggressivity
13 
14 class Dog:  # 定义一个狗类
15     role = 'dog'  # 狗的角色属性都是狗
16 
17     def __init__(self, name, breed, aggressivity, life_value):
18         self.name = name  # 每一只狗都有自己的昵称;
19         self.breed = breed  # 每一只狗都有自己的品种;
20         self.aggressivity = aggressivity  # 每一只狗都有自己的攻击力;
21         self.life_value = life_value  # 每一只狗都有自己的生命值;
22 
23     def bite(self,people):
24         # 狗可以咬人,这里的狗也是一个对象。
25         # 狗咬人,那么人的生命值就会根据狗的攻击力而下降
26         people.life_value -= self.aggressivity
27 
28 egg = Person('egon',10,1000)  #创造了一个实实在在的人egg
29 ha2 = Dog('二愣子','哈士奇',10,1000)  #创造了一只实实在在的狗ha2
30 print(ha2.life_value)         #看看ha2的生命值
31 egg.attack(ha2)               #egg打了ha2一下
32 print(ha2.life_value)         #ha2掉了10点血
egon大战哈士奇
 1 from math import pi
 2 
 3 class Circle:
 4     '''
 5     定义了一个圆形类;
 6     提供计算面积(area)和周长(perimeter)的方法
 7     '''
 8     def __init__(self,radius):
 9         self.radius = radius
10 
11     def area(self):
12          return pi * self.radius * self.radius
13 
14     def perimeter(self):
15         return 2 * pi *self.radius
16 
17 
18 circle =  Circle(10) #实例化一个圆
19 area1 = circle.area() #计算圆面积
20 per1 = circle.perimeter() #计算圆周长
21 print(area1,per1) #打印圆面积和周长
一个简单的例子帮你理解面向对象

类命名空间与对象、实例的命名空间

创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

而类有两种属性:静态属性和动态属性

  • 静态属性就是直接在类中定义的变量
  • 动态属性就是定义在类中的方法

其中类的数据属性是共享给所有对象的

1 >>>id(egg.role)
2 4341594072
3 >>>id(Person.role)
4 4341594072
View Code

创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性

在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常

面向对象的组合用法

软件重用的重要方式除了继承之外还有另外一种方式,即:组合

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

 1 class Weapon:
 2     def prick(self, obj):  # 这是该装备的主动技能,扎死对方
 3         obj.life_value -= 500  # 假设攻击力是500
 4 
 5 class Person:  # 定义一个人类
 6     role = 'person'  # 人的角色属性都是人
 7 
 8     def __init__(self, name):
 9         self.name = name  # 每一个角色都有自己的昵称;
10         self.weapon = Weapon()  # 给角色绑定一个武器;
11         
12 egg = Person('egon')
13 egg.weapon.prick() 
14 #egg组合了一个武器的对象,可以直接egg.weapon来使用组合类中的所有方法
View Code

圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用

 1 from math import pi
 2 
 3 class Circle:
 4     '''
 5     定义了一个圆形类;
 6     提供计算面积(area)和周长(perimeter)的方法
 7     '''
 8     def __init__(self,radius):
 9         self.radius = radius
10 
11     def area(self):
12          return pi * self.radius * self.radius
13 
14     def perimeter(self):
15         return 2 * pi *self.radius
16 
17 
18 circle =  Circle(10) #实例化一个圆
19 area1 = circle.area() #计算圆面积
20 per1 = circle.perimeter() #计算圆周长
21 print(area1,per1) #打印圆面积和周长
22 
23 class Ring:
24     '''
25     定义了一个圆环类
26     提供圆环的面积和周长的方法
27     '''
28     def __init__(self,radius_outside,radius_inside):
29         self.outsid_circle = Circle(radius_outside)
30         self.inside_circle = Circle(radius_inside)
31 
32     def area(self):
33         return self.outsid_circle.area() - self.inside_circle.area()
34 
35     def perimeter(self):
36         return  self.outsid_circle.perimeter() + self.inside_circle.perimeter()
37 
38 
39 ring = Ring(10,5) #实例化一个环形
40 print(ring.perimeter()) #计算环形的周长
41 print(ring.area()) #计算环形的面积
View Code

用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程

 1 class BirthDate:
 2     def __init__(self,year,month,day):
 3         self.year=year
 4         self.month=month
 5         self.day=day
 6 
 7 class Couse:
 8     def __init__(self,name,price,period):
 9         self.name=name
10         self.price=price
11         self.period=period
12 
13 class Teacher:
14     def __init__(self,name,gender,birth,course):
15         self.name=name 
16         self.gender=gender
17         self.birth=birth
18         self.course=course
19     def teach(self): 
20         print('teaching')
21 
22 p1=Teacher('egon','male', 
23             BirthDate('1995','1','27'), 
24             Couse('python','28000','4 months')
25            ) 
26 
27 print(p1.birth.year,p1.birth.month,p1.birth.day) 
28 
29 print(p1.course.name,p1.course.price,p1.course.period)
30 ''' 
31 运行结果: 
32 27 
33 python 28000 4 months 
34 '''
View Code

当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

初识面向对象小结

定义一个人类

 1 class Person:  # 定义一个人类
 2     role = 'person'  # 人的角色属性都是人
 3 
 4     def __init__(self, name, aggressivity, life_value, money):
 5         self.name = name  # 每一个角色都有自己的昵称;
 6         self.aggressivity = aggressivity  # 每一个角色都有自己的攻击力;
 7         self.life_value = life_value  # 每一个角色都有自己的生命值;
 8         self.money = money
 9 
10     def attack(self,dog):
11         # 人可以攻击狗,这里的狗也是一个对象。
12         # 人攻击狗,那么狗的生命值就会根据人的攻击力而下降
13         dog.life_value -= self.aggressivity
View Code

定义一个狗类

 1 class Dog:  # 定义一个狗类
 2     role = 'dog'  # 狗的角色属性都是狗
 3 
 4     def __init__(self, name, breed, aggressivity, life_value):
 5         self.name = name  # 每一只狗都有自己的昵称;
 6         self.breed = breed  # 每一只狗都有自己的品种;
 7         self.aggressivity = aggressivity  # 每一只狗都有自己的攻击力;
 8         self.life_value = life_value  # 每一只狗都有自己的生命值;
 9 
10     def bite(self,people):
11         # 狗可以咬人,这里的狗也是一个对象。
12         # 狗咬人,那么人的生命值就会根据狗的攻击力而下降
13         people.life_value -= self.aggressivity
View Code

接下来,又创建一个新的兵器类。

 1 class Weapon:
 2     def __init__(self,name, price, aggrev, life_value):
 3         self.name = name
 4         self.price = price
 5         self.aggrev = aggrev
 6         self.life_value = life_value
 7 
 8     def update(self, obj):  #obj就是要带这个装备的人
 9         obj.money -= self.price  # 用这个武器的人花钱买所以对应的钱要减少
10         obj.aggressivity += self.aggrev  # 带上这个装备可以让人增加攻击
11         obj.life_value += self.life_value  # 带上这个装备可以让人增加生命值
12 
13     def prick(self, obj):  # 这是该装备的主动技能,扎死对方
14         obj.life_value -= 500  # 假设攻击力是500
View Code

测试交互

 1 lance = Weapon('长矛',200,6,100)
 2 egg = Person('egon',10,1000,600)  #创造了一个实实在在的人egg
 3 ha2 = Dog('二愣子','哈士奇',10,1000)  #创造了一只实实在在的狗ha2
 4 
 5 #egg独自力战"二愣子"深感吃力,决定穷毕生积蓄买一把武器
 6 if egg.money > lance.price: #如果egg的钱比装备的价格多,可以买一把长矛
 7     lance.update(egg) #egg花钱买了一个长矛防身,且自身属性得到了提高
 8     egg.weapon = lance #egg装备上了长矛
 9 
10 print(egg.money,egg.life_value,egg.aggressivity)
11 
12 print(ha2.life_value)
13 egg.attack(ha2)   #egg打了ha2一下
14 print(ha2.life_value)
15 egg.weapon.prick(ha2) #发动武器技能
16 print(ha2.life_value) #ha2不敌狡猾的人类用武器取胜,血槽空了一半
View Code

按照这种思路一点一点的设计类和对象,最终你完全可以实现一个对战类游戏。

课堂训练代码:

 1 class Person:
 2     role = 'person'   # 静态属性
 3     def __init__(self,name,sex,hp,ad):
 4         self.name = name     # 对象属性 属性
 5         self.sex = sex
 6         self.hp = hp         #血量
 7         self.ad = ad         #攻击力
 8     def attack(self,d):
 9         d.hp -= self.ad
10         print('%s攻击了%s,%s掉了%s点血'%(self.name,d.name,d.name,self.ad))
11 
12 class Dog:
13     def __init__(self,name,kind,hp,ad):
14         self.name = name
15         self.kind = kind
16         self.hp = hp
17         self.ad = ad
18     def bite(self,p):
19         p.hp -= self.ad
20         print('%s咬了%s一口,%s掉了%s点血' % (self.name, p.name, p.name, self.ad))
21 
22 alex = Person('a_sb','不详',1,5)
23 boss_jin = Person('金老板','',20,50)
24 teddy = Dog('笨笨','teddy',50,10)
25 teddy.bite(alex)
26 print(alex.hp)
27 boss_jin.attack(teddy)
28 print(teddy.hp)
29 
30 # alex.attack()      # Person.attack(alex)
31 # boss_jin.attack()  # Person.attack(boss_jin)
32 
33 # 人和狗
34 # 4个技能 玩家可以选择技能
面向对象课堂练习代码
  1 class Person:
  2 #     role = 'person'   # 静态属性
  3 #     def __init__(self,name,sex,hp,ad):
  4 #         self.name = name     # 对象属性 属性
  5 #         self.sex = sex
  6 #         self.hp = hp
  7 #         self.ad = ad
  8 #     def attack(self):
  9 #         self.hobby = 'girl'
 10 #         print('%s发起了一次攻击'%self.name)
 11 #
 12 # alex = Person('a_sb','不详',1,5)
 13 # alex.attack()   # Person.attack(alex)
 14 # alex.age = 81
 15 # # alex --> Person
 16 # # Person实例化了alex
 17 # print(alex.__dict__)
 18 
 19 # alex.name   #alex 指向我自己的内存空间 在自己的内存空间里找到name
 20 # alex.attack #alex 先找自己的内存空间 再找到类对象指针 再根据类对象指针找到类 再通过类找到attack
 21 # 对象的内存空间里: 只存储对象的属性,而不存储方法和静态属性
 22 # 方法和静态属性都存储在类的内存空间中
 23 # 为了节省内存,让多个对象去共享类中的资源
 24 
 25 
 26 # class Person:
 27 #     role = 'person'   # 静态属性
 28 #     def __init__(self,name,sex,hp,ad):
 29 #         self.name = name     # 对象属性 属性
 30 #         self.sex = sex
 31 #         self.hp = hp
 32 #         self.ad = ad
 33 #         self.attack = 'hahaha'
 34 #     def attack(self):
 35 #         print('%s发起了一次攻击'%self.name)
 36 #
 37 # alex = Person('a_sb','不详',1,5)
 38 # boss_jin = Person('金老板','女',50,20)
 39 # print(alex.role)
 40 # print(boss_jin.role)
 41 # alex.role = 'dog'
 42 # print(alex.role)
 43 # print(boss_jin.role)    # dog or ? person
 44 
 45 
 46 
 47 # class Person:
 48 #     role = 'person'   # 静态属性
 49 #     def __init__(self,name,sex,hp,ad):
 50 #         self.name = name     # 对象属性 属性
 51 #         self.sex = sex
 52 #         self.hp = hp
 53 #         self.ad = ad
 54 #         self.attack = 'hahaha'
 55 #     def attack(self):
 56 #         print('%s发起了一次攻击'%self.name)
 57 #
 58 # alex = Person('a_sb','不详',1,5)
 59 # boss_jin = Person('金老板','女',50,20)
 60 # print(alex.role)
 61 # print(boss_jin.role)
 62 # alex.role = 'dog'
 63 # print(alex.role)
 64 # 模拟人生
 65 # class Person:
 66 #     money = 0
 67 #     def __init__(self,name):
 68 #         self.name = name
 69 #     def work(self):
 70 #         print(self.name,'工作,赚了1000块钱')
 71 #         Person.money += 1000
 72 #
 73 # father = Person('father')
 74 # mother = Person('mother')
 75 # mother.work()
 76 # father.work()
 77 # print(Person.money)
 78 
 79 
 80 # 写一个类 完成一个功能 : 可以统计这个类有几个对象
 81 # class Foo:
 82 #     count = 0
 83 #     def __init__(self):
 84 #         Foo.count += 1
 85 # f1 = Foo()
 86 # f2 = Foo()
 87 # f3 = Foo()
 88 # f4 = Foo()
 89 # f5 = Foo()
 90 # print(Foo.count)  #
 91 
 92 
 93 
 94 # class Person:
 95 #     money = [1]
 96 #     def __init__(self,name):
 97 #         self.name = name
 98 #     def work(self):
 99 #         print(self.name,'工作,赚了1000块钱')
100 #         self.money[0] += 1000
101 #
102 # father = Person('father')
103 # mother = Person('mother')
104 # mother.work()
105 # father.work()
106 # print(Person.money)   # 2000 or 0?
107 
108 # class Person:
109 #     money = [0]
110 #     def __init__(self,name):
111 #         self.name = name
112 #     def work(self):
113 #         print(self.name,'工作,赚了1000块钱')
114 #         Person.money =  [Person.money[0] + 1000]
115 #
116 # father = Person('father')
117 # mother = Person('mother')
118 # mother.work()
119 # father.work()
120 # print(Person.money)
121 
122 # 对象属性是独有的,静态属性和方法是共享的
123 # 对象使用名字:先找自己内存空间中的,再找类的内存空间中的
124 # 类名.静态变量名 :对于静态属性的修改,应该使用类名直接修改
命名空间和作用域
 1  2 # 计算圆的周长 2 pi r
 3 # 计算圆的面积 pi r**2
 4 # 5个圆
 5 # 1,3,5,7,9
 6 from math import pi
 7 class Circle:
 8     def __init__(self,r):
 9         self.r = r
10     def cal_area(self):
11         '''
12         计算圆面积的方法
13         :return:返回值是float数据类型的面积
14         '''
15         return pi*self.r**2
16     def cal_perimeter(self):
17         '''
18         计算圆周长的方法
19         :return:返回值是float数据类型的周长
20         '''
21         return pi * self.r * 2
22 for i in range(1,10,2):
23     c1 = Circle(i)
24     print(c1.cal_area())
25     print(c1.cal_perimeter())
26 # 类 属性 和 方法
27     # 半径
28     # 计算面积 计算周长
29 # 程序的解耦
30     # 当计算的规模足够大的时候 我们应该在编码的过程当中让操作尽量原子化
31     # 尽量用返回值来代替print
32 
33 # 面向对象的基础
34 
35 # 用面向对象的思想
36 # 1.博客上的练一练
37 # 2.计算圆环的面积和周长
38 # 3.默写 交互
39 # 4.校园管理系统第一步
面向对象实例

 

posted @ 2018-04-11 21:09  大白1#  阅读(66)  评论(0)    收藏  举报