全民一起玩Python提高篇第十三课:面向对象基本原理与语法(四)

消息机制

创建游戏主程序

from 游戏人物 import Role

r1=Role('程咬金',5,200)
r2=Role('王昭君',10,100)

r1.attack(r2)
r2.attack(r1)

人物属性

class  Role:
    def __init__(self,name,power,blood):
        self.name=name
        self.power=power
        self.blood=blood

    def attack(self,enemy):
        print(f'{self.name}对{enemy.name}发起{self.power}点暴击!')
        enemy.hurt(self.power)
        #虽然受伤是被动造成的,但还是应该算到对方的一个属性去
        #自己的attack调用了敌人的hurt方法来实现,产生交互了
    def hurt(self,p):
        #p为对方的攻击力
        self.blood-=p
        print(f'{self.name}血量降到{self.blood}')

    def die(self):
        print(f'{self.name}卒')

不同类型,统一方法,可统一调用–多态
父类下面的子类,拥有父类的属性–继承
定义父类,将所有的属性封装在同一段代码中–封装

游戏主程序

from 游戏人物 import Role
from 游戏人物 import Player
from random import sample
from time import sleep

roles=[Role('王昭君',10,100),
           Role('后羿',20,50),
            Role('程咬金',30,30),
            Player('锦到黑',50,200)]

while len(roles)>1:
    #只要还剩两个及以上角色,就可以打
    本轮对手=sample(roles,2)
    r1=本轮对手[0]
    r2=本轮对手[1]
    r1.attack(r2)
    if r2.blood<=0:
        r2.die()
        roles.remove(r2)
        #死亡后删除出列表
    sleep(0.5)
print(f'最终获胜者是--{roles[0].name}!')

类定义

from random import randint
class  Role:
    def __init__(self,name,power,blood):
        self.name=name
        self.power=power
        self.blood=blood

    def attack(self,enemy):
        print(f'{self.name}对{enemy.name}发起{self.power}点暴击!')
        enemy.hurt(self.power)
        #虽然受伤是被动造成的,但还是应该算到对方的一个属性去
        #自己的attack调用了敌人的hurt方法来实现,产生交互了
    def hurt(self,p):
        #p为对方的攻击力
        self.blood-=p
        print(f'{self.name}血量降到{self.blood}')

    def die(self):
        print(f'{self.name}卒')

class Player(Role):
    def attack(self,enemy):
        s=input(f'请{self.name}选择对{enemy.name}的攻击方式,1-常规,2-疯狗')
        if s=='1':
            enemy.hurt(self.power)
        elif s=='2':
            enemy.hurt(randint(0,3)*self.power)
            self.blood-=3
        else:
            print('输入错误,错过本次攻击!')

效果
在这里插入图片描述

题目:将对象作为参数

假设要开发一个学校综合管理系统,你负责其中学生管理这个模块。因而需要定义两个类:学生名册类和学生类。
其中学生类的每个对象都应该有姓名、年龄和分数三个属性,一个学生对象代表一个具体的学生;
而学生名册类有一个“学生名单”属性,类型为列表,用于保存所有学生对象。同时该类提供一个add方法,当用户需要添加一个学生到“学生名单”中时,只要调用该方法,并把学生对象作为参数传递给它就可以。同时学生名册类还提供一个names方法,可以打印名单中所有学生的姓名。
请按如上要求编写这两个类。然后在主程序中创建多个学生对象,再使用“学生名册”类的相关方法,将它们添加到名册中,最后把他们的姓名都打印在屏幕上。

class   Student:
    def __init__(self,name,age,grade):
        self.name=name
        self.age=age
        self.grade=grade

class Student_List:
    def __init__(self,Stu_List):
        self.Stu_List=Stu_List

    def Add(self,Student):
        self.Stu_List.append(Student)

    def names(self):
        for i in self.Stu_List:
            print(f'姓名是{i.name},年龄是{i.age},年级是{i.grade}')

if __name__=='__main__':
    stu1=Student('锦到黑','18','1')
    stu2=Student('锦到黑黑','19','2')
    stu3 = Student('锦到黑黑黑', '20', '3')
    stu4=Student('锦到黑黑黑黑','21','4')
    stu_list=Student_List([stu1,stu2,stu3])
    #传入三个学生类对象
    stu_list.Add(stu4)
    stu_list.names()

假设编写一个“CPU能力测试”程序时,需要创建 CPU 类和测试器类。其中 CPU 类拥有一个型号属性,而测试器类拥有测试方法,名为 test。
调用测试器类的 test方法时,需要把一个CPU对象作为参数传递给它,然后该方法会显示出该CPU对象的具体型号、打印在屏幕上。
编写上述类后,请在主程序中国创建两个不同型号的CPU对象,然后用一个测试器类的对象,分别显示它们的型号。

class CPU:
    def __init__(self,CPU_Type):
        self.CPU_Type=CPU_Type

class Test_Tool:
    def Test(self,CPU):
        print(f'该CPU的型号为{CPU.CPU_Type}')

if __name__=='__main__':
    cpu1=CPU('IBM')
    cpu2=CPU('Intel')
    Test_tool=Test_Tool()
    Test_tool.Test(cpu1)
    Test_tool.Test(cpu2)

题目:对象作为属性

假设正在编写一个工程设计计算软件,其中需要用到几个常用的几何形体类:
长方体类Cuboid,拥有两个属性“底面积”s 和 “高度” h ,并有一个计算自己体积的方法 calc ,可以根据公式 s * h 计算出体积数值并返回。
方锥体类Pyramid(即金字塔形状),也拥有两个属性“底面积”s 和 “高度” h ,并有一个计算自己体积的方法 calc ,可以根据公式 s * h / 3 计算出体积数值并返回。
方尖碑类Obelisk,是由一个长方体类和一个方锥体类组合而成的物体。因而该类拥有两个属性,分别是一个长方体对象和一个方锥体对象。同时该方尖碑也拥有一个方法calc,可以计算返回方尖碑的体积,计算方法就是将两个属性(长方体与方锥体)的体积相加。
请按上述要求编写这三个类的代码。然后在主程序中创建一个长方体、一个方椎体,并用二者作为属性创建一个方尖碑对象。接下来让该方尖碑对象打印出自己的总体积。

class Cuboid:
    def __init__(self,s,h):
        self.s=s
        self.h=h

    def calc(self):
        return self.s*self.h

class Pyramid:
    def __init__(self,s,h):
        self.s=s
        self.h=h

    def calc(self):
        return self.s*self.h/3

class Obelisk:
    def __init__(self,Cuboid,Pyramid):
        self.cuboid = Cuboid
        self.pyramid = Pyramid
    def calc(self):
        print(self.cuboid.calc()+self.pyramid.calc())

if __name__=='__main__':
    p=Pyramid(14,15)
    c=Cuboid(3,4)
    obelisk=Obelisk(p,c)
    obelisk.calc()

自定义类

list单独打印只能得到整个list,而不是将每一个list中的数单独打印
所以自己定义一个对象

 class my_list(list):
...    def print(self):
...        for x in self:
...            print(x)
...            
>>> a=my_list([2,3,4,1])
>>> a.print()
2
3
4
1

这样a.就会弹出print这一个方法
这样自定义的列表可以作为强制转换的

b=[2,1,1,3]
my_list(b).print()
2
1
1
3

python自带的print,使用的是__repr__方法,可以通过设置同名方法来进行多态处理

class my_list(list):
#这里my_list就是list的一个子类
    def __repr__(self):
        for x in self:
            print(x)
        return ''

a=my_list([1,2,34])
b=[1,2,3,4]

print(a)
print(b)

类属性的定义

class Mishu:
    name='无'
    age=0
    #属性的模板
    def say_hello(self):
        print('你好')

a=Mishu()
print(Mishu.name)
print(a.name)
#写在类定义中,每个具体对象,和这个抽象对象都能调用
#这种方便给每一个对象赋予相同的属性,方便修改和调用

查看某一个对象属于什么类型

class my_list(list):
#这里my_list就是list的一个子类
    def __repr__(self):
        for x in self:
            print(x)
        return ''

a=my_list([1,2,34])
print(type(a))
print(isinstance(a,list))
#可以判断某一子类是否属于父类
print(my_list.mro())
#返回所有父类类型
print(dir(my_list))
#可以查到所有的属性方法

空对象

def my_func():
    return
#返回的是一个None,空对象
i=my_func()
if i is None:
    print('空对象')

题目:统计随机数

请先生成一个列表,包含20个从1到20的随机数。然后使用Python标准库的Counter类,求每一种数字重复的次数

from random import randint
from collections import Counter
my_list=[]
for i in range(20):
    my_list.append(randint(1,20))
c=Counter(my_list)
print(c)

题目:自定义print

请自定义一个列表类来扩展python列表的功能,使创建的列表在打印时可以把重复元素只显示一个,而且打印的元素用空格分隔。
比如对于列表 [ 3 ,3 , 2, 1, 2, 4 ] ,
输出结果应为: 3 2 1 4 。
提示:
(1) 去重可以利用集合类的特点;
(2) repre 方法的标准形式是把要打印的内容生成一个字符串,然后把这个字符串用return语句返回。而 print函数等会自动把 repre 返回的字符串打印在屏幕上。

class my_list(list):
#这里my_list就是list的一个子类
    def __repr__(self):
        my_set=set(self)
        for i in my_set:
            print(i)
        return ''
        #这个return ''不能少
a=my_list([1,2,341,1,1,1,1,1,1,2,3,3,3,3,4,2])
print(a)

题目:类属性的应用

类属性的功能之一,是作为“计数器”来记录该类对象的实例总数,而该数字也可以用来给该类对象自动分配一个“唯一流水号”。
请修改上一回(第40回)作业中的学生系统程序,在“学生类”中增加一个类属性,用作“学生总数计数器”。
这样,每当添加一个学生时,添加方法都调用类属性,更新目前的学生总数。
然后在主程序中添加多个学生对象;再调用学生类的该属性、打印出学生总数。

class Student:
    count = 0 
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score
        
class System:
    def __init__(self):
        self.stus = []
    def add(self, stu):
        self.stus.append(stu)
        Student.count += 1
        
sys = System()
sys.add(Student('张三', 22, 87))
sys.add(Student('李四', 21, 74))
sys.add(Student('王五', 20, 92))
print('学生个数为:', Student.count)

题目:设计面向对象系统

综合题:请设计一个大学校园人员信息管理系统,该系统拥有5个模块:大学、人员、教授、学生、社团、教务。功能需求如下所示:

  1. 大学模块记录大学名称和位置;
  2. 人员模块的信息有姓名、电话、电子邮箱地址,功能有收电子邮件和发电子邮件;
  3. 教授模块的信息有姓名、电话、电子邮箱地址、工作证号和工龄,功能有授课、收发电子邮件;
  4. 学生模块的信息有姓名、电话、电子邮箱地址、学号、班级,功能有考试、收发电子邮件;
  5. 社团模块的信息有名称、活动时间;
  6. 教务模块的信息有教授和学生的姓名、电话、电子邮箱地址以及教授的工作证号、工龄、学生的学号、班级。
    提示:本题目为开放性练习,不具有标准答案,可以根据自己的想法进行设计和讨论。
class people:
    def __init__(self,name,phone,email):
        self.name=name
        self.phone=phone
        self.email=email
    def send_email(self):
        print('发邮件')

    def receive_email(self):
        print('收邮件')

class professor(people):
    def __init__(self, name, phone,email,work_ID,work_year):
        self.work_ID = work_ID
        self.work_year =work_year
        people.__init__(self, name, phone,email)

    def teaching(self):
        print('教授有上课的任务')

class student(people):
    def __init__(self, name, phone,email,stu_ID,stu_class):
        self.stu_ID = stu_ID
        self.stu_class =stu_class
        people.__init__(self, name, phone,email)

    def exam(self):
        print('学生有参加考试的任务')
class union:
    def __init__(self,name,time):
        self.name=name
        self.time=time

class teach(professor,student):
    def __init__(self,professor,student):
        self.pro_name=professor.name
        self.pro_phone=professor.phone
        self.pro_email=professor.email
        self.pro_ID=professor.work_ID
        self.pro_year=professor.work_year
        self.stu_name=student.name
        self.stu_phone=student.phone
        self.stu_email = student.email
        self.stu_ID = student.stu_ID
        self.stu_class =student.stu_class

    def show(self):
        print(self.pro_name,self.pro_phone,self.pro_email,self.pro_ID,self.pro_year,
                self.stu_name,self.stu_phone,self.stu_email,self.stu_ID,self.stu_class)
if __name__=='__main__':
    pro1=professor('锦到黑','13113113111','jindaohei@qq.com','20200202',20)
    stu1=student('到黑锦','88208300','daohei@qq.com','B212305','Senior')
    teach1=teach(pro1,stu1)
    teach1.show()
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值