Python基础之面向对象2(封装)
一、封装定义:
二、作用
三、私有成员:
1、基本概念及作用
2、__slots__手段私有成员:
3、@property属性手段私有成员:
四、基础示例代码
1、用方法封装变量
"""
练习:用方法封装变量
"""
class Enemy:
def __init__(self,name,atk,speed,hp):
self.set_name(name)
self.set_atk(atk)
self.set_atk_speed(speed)
self.set_hp(hp) def get_name(self):
return self.__name def set_name(self,value):
self.__name = value def get_atk(self):
return self.__atk def set_atk(self, value):
self.__atk = value def get_atk_speed(self):
return self.__atk_speed def set_atk_speed(self, value):
if 0 <= value <= 10:
self.__atk_speed = value
else:
self.__atk_speed = 0
print("速度不再范围内,赋值失败") def get_hp(self):
return self.__hp def set_hp(self, value):
if 0 <= value <= 100:
self.__hp = value
else:
self.__hp = 0
print("血量不再范围内,赋值失败") e01 = Enemy("zs",200,50,200)
print(e01.get_name(),e01.get_hp(),e01.get_atk_speed())
2、用属性封装变量:
"""
练习:属性封装变量
""" class Enemy:
def __init__(self, name, atk, speed, hp):
self.name = name
self.atk = atk
self.speed = speed
self.hp = hp @property
def name(self):
return self.__name @name.setter
def name(self,value):
self.__name = value @property
def atk(self):
return self.__atk @atk.setter
def atk(self, value):
self.__atk = value @property
def speed(self):
return self.__speed @speed.setter
def speed(self, value):
self.__speed = value @property
def hp(self):
return self.__hp @hp.setter
def hp(self, value):
self.__hp= value e01 = Enemy("zs", 200, 50, 200)
print(e01.name, e01.hp, e01.speed)
3、基础代码1
"""
封装数据优势:
1.符合人类思考方式
2.将数据与对数据的操作封装起来。 使用方法封装变量
""" class Wife01:
def __init__(self, name, age):
self.name = name
# 缺点:缺乏对象数据的封装,外界可以随意赋值.
self.age = age w01 = Wife01("芳芳", 26)
w02 = Wife01("铁锤", 86)
w02.age = 87
# print(w02.age) # 注意:通过两个方法,读写私有变量.
# 练习:定义敌人类(姓名,攻击力,攻击速度(0-10),血量(0--100))
class Wife02:
def __init__(self, name = "", age = 0):
self.set_name(name)
# 私有成员:障眼法(解释器会改变双下划线开头的变量名)
# self.__age = age
self.set_age(age) def get_name(self):
return self.__name def set_name(self,value):
self.__name = value def get_age(self):
return self.__age def set_age(self,value):
if 20 <= value <= 30:
self.__age = value
else:
print("我不要") w01 = Wife02("铁锤",86)
# 找不到双下划线开头的数据
# print(w01.__age)
# 通过下划线 + 类名 可以访问双下划线开头的数据
# print(w01._Wife02__age)
w01.set_age(50)
print(w01.get_age())
print(w01.__dict__)
4、基础代码2:
"""
使用属性封装变量
""" # 练习:修改Enemy类,使用属性封装变量
class Wife:
def __init__(self, name="", age=0):
self.name = name # 调用 @name.setter 修饰的方法
self.age = age # 调用 @age.setter 修饰的方法 @property # 拦截读取变量的操作
def name(self): # get_name()
return self.__name @name.setter # 拦截写入变量的操作
def name(self, value): # set_name()
self.__name = value @property
def age(self):
return self.__age @age.setter
def age(self, value):
if 20 <= value <= 30:
self.__age = value
else:
self.__age = 0
print("我不要") w01 = Wife("铁锤", 86)
print(w01.name)
print(w01.age)
5、基础代码3:
"""
__slots__ 属性
"""
class SkillData:
# 限制当前类,创建的对象,只能具有的实例变量.
__slots__ = ("__name") def __init__(self, name):
self.name = name @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value s01 = SkillData("技能名称")
# s01.name = "降龙十八掌"
print(s01.name)
# 为当前对象,添加实例变量
# s01.time = 5
# print(s01.time)
# print(s01.__dict__) # 因为使用了__slots__属性,所以不是使用__dict__.
6、基础代码4:
"""
需求: 老张开去车东北.
分而治之 -- 分解
变化点
练习:exercise01
""" #需求: 老张开去车东北.
class Person:
def __init__(self, name):
self.name = name def go_to(self, type, str_pos):
type.run(str_pos) class Car:
def run(self, str_pos):
print("行驶到", str_pos) p01 = Person("老张")
c01 = Car()
p01.go_to(c01, "东北")
五、实例练习:
练习1:
"""
以面向对象的思想,描述下列场景.
提示:对象与对象数据不同,类与类行为不同.
张三 教 李四 学习python
李四 教 张三 玩游戏
张三 工作 挣了8000元
李四 工作 挣了3000元
""" class Person:
def __init__(self, name):
# 人的姓名
self.name = name
# 人会的所有技能
self.__skills = []
self.__total_money = 0 # 只读属性
@property
def skills(self):
# return self.__skills # 返回可变对象地址,意味着类外仍然可以操作可变对象
return self.__skills[:] # 返回新的可变对象地址,意味着类外仍然操作的是新可变对象,不影响原对象.
# 备注:每次通过切片返回新对象,都会另外开辟空间创建新对象,占用过多内存. # 只读属性
@property
def total_money(self):
return self.__total_money @property
def name(self):
return self.__name @name.setter
def name(self,value):
self.__name = value def teach(self, person_other, str_skill):
# person_other 的技能列表,增加str_skill
person_other.__skills.append(str_skill)
print(self.name, "教了", person_other.name, str_skill) def work(self, money):
self.__total_money += money
print(self.name, "工作挣了", money, "元") zs = Person("张三")
ls = Person("李四")
# 张三 教 李四 学习python
zs.teach(ls, "python")
# 李四 教 张三 玩游戏
ls.teach(zs, "游戏") zs.work(8000)
ls.work(4000) #************************
zs = Person("张三")
# zs.skills = [] # 不能改
# 如果skills属性,返回的是__skills,那么仍然可以操作私有列表
# __skills[:],那么操作的是新列表
zs.skills.append("python")
print(zs.skills)
练习2:
"""
创建技能类(技能名称,冷却时间,持续时间,攻击距离......)
要求:使用属性封装变量
创建技能列表(技能对象的列表)
-- 查找名称是"降龙十八掌"的技能对象
-- 查找名称是持续时间大于10秒的的所有技能对象
-- 查找攻击距离最远的技能对象
-- 按照持续时间,对列表升序排列.
""" class SkillData:
def __init__(self, name, cd, time, distance):
self.name = name
self.cd = cd
self.time = time
self.atk_distance = distance @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value @property
def cd(self):
return self.__cd @cd.setter
def cd(self, value):
self.__cd = value @property
def time(self):
return self.__time @time.setter
def time(self, value):
self.__time = value @property
def atk_distance(self):
return self.__atk_distance @atk_distance.setter
def atk_distance(self, value):
self.__atk_distance = value def print_self(self):
print(self.name, self.cd, self.time, self.atk_distance) list_skills = [
SkillData("降龙十八掌", 60, 10, 5),
SkillData("如来神掌", 50, 5, 15),
SkillData("六脉神剑", 80, 20, 8),
SkillData("一阳指", 20, 50, 15),
SkillData("冷酷追击", 15, 30, 9),
] # -- 查找名称是"降龙十八掌"的技能对象
for item in list_skills:
if item.name == "降龙十八掌":
item.print_self() # -- 查找名称是持续时间大于10秒的的所有技能对象
result = []
for item in list_skills:
if item.time > 10:
result.append(item) # -- 查找攻击距离最远的技能对象
result = list_skills[0]
for i in range(1, len(list_skills)):
# 后面的技能对象
if result.atk_distance < list_skills[i].atk_distance:
result = list_skills[i]
# result.atk_distance = list_skills[i].atk_distance result.print_self() # -- 按照持续时间,对列表升序排列.
for r in range(len(list_skills) - 1):
for c in range(r + 1, len(list_skills)):
if list_skills[r].time > list_skills[c].time:
list_skills[r],list_skills[c] = list_skills[c],list_skills[r] # 请用调试,查看列表的取值.
print(list_skills)
练习3:
# 练习: 小明在招商银行取钱.
class Person:
def __init__(self, name, money=0):
self.name = name
self.money = money class Bank:
def __init__(self, name, money):
self.name = name
self.total_money = money # 考虑:取钱逻辑,应该由银行决定.所以取钱方法,定义在了银行.
def draw_money(self, person, value):
if self.total_money >= value:
self.total_money -= value
person.money += value
print(person.name, "取钱成功")
else:
print("取钱失败") p01 = Person("小明")
b01 = Bank("招商银行", 100000)
b01.draw_money(p01, 10000000)
练习4
"""
学生管理器系统
""" class StudentModel:
"""
学生数据模型类
""" def __init__(self, name="", age=0, score=0, id=0):
"""
创建学生对象
:param id: 编号
:param name: 姓名
:param age: 年龄
:param score: 成绩
"""
self.id = id
self.name = name
self.age = age
self.score = score @property
def id(self):
return self.__id @id.setter
def id(self, value):
self.__id = value @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value @property
def age(self):
return self.__age @age.setter
def age(self, value):
self.__age = value @property
def score(self):
return self.__score @score.setter
def score(self, value):
self.__score = value class StudentManagerController:
"""
学生逻辑控制器
""" def __init__(self):
self.__list_stu = [] @property
def list_stu(self):
return self.__list_stu def add_student(self, stu):
"""
添加新学生
:param stu: 需要添加的学生对象
"""
stu.id = self.__generate_id()
self.__list_stu.append(stu) def __generate_id(self):
# 生成编号的需求:新编号,比上次添加的对象编号多1.
# if len(self.__list_stu) > 0:
# id = self.__list_stu[-1].id + 1
# else:
# id = 1
# return id
return self.__list_stu[-1].id + 1 if len(self.__list_stu) > 0 else 1 # controller = StudentManagerController()
# controller.add_student(StudentModel("zs",18,85))
# controller.add_student(StudentModel("zs",18,85))
# for item in controller.list_stu:
# print(item.id,item.name,item.age,item.score) class StudentManagerView:
"""
界面视图类
"""
def __init__(self):
# 创建逻辑控制器对象
self.__manager = StudentManagerController() def __input_students(self):
# 1. 在控制台中录入学生信息,存成学生对象StudentModel.
stu = StudentModel()
stu.name = input("请输入姓名:")
stu.age = int(input("请输入年龄:"))
stu.score = int(input("请输入成绩:"))
# 2. 调用逻辑控制器的add_student方法
self.__manager.add_student(stu)
print(self.__manager) def __display_menu(self):
"""
显示菜单
:return:
"""
print("1) 添加学生")
print("2) 显示学生")
print("3) 删除学生")
print("4) 修改学生")
print("5) 按照成绩降序排列") def __select_menu(self):
"""
选择菜单
:return:
"""
number = input("请输入选项:")
if number == "":
self.__input_students()
elif number == "":
pass
elif number == "":
pass
elif number == "":
pass
elif number == "":
pass def main(self):
"""
界面入口方法
:return:
"""
while True:
self.__display_menu()
self.__select_menu() view = StudentManagerView()
view.main()
内存图如下:
练习5
# 1. 使用面向对象思想,写出下列场景:
# 玩家(攻击力)攻击敌人,敌人受伤(血量)后掉血,还可能死亡(播放动画).
# 敌人(攻击力)攻击力攻击玩家,玩家(血量)受伤后碎屏,还可能死亡(游戏结束).
# 程序调试,画出内存图. class Player:
"""
玩家类
"""
def __init__(self,hp,atk):
self.atk = atk
self.hp = hp def attack(self,enemy):
print("打死你")
# 调用敌人受伤方法(敌人负责定义受伤逻辑)
enemy.damage(self.atk) def damage(self,value):
self.hp -= value
print("玩家受伤啦,屏幕碎啦")
if self.hp <= 0:
self.__death() def __death(self):
print("玩家死亡,游戏结束") class Enemy:
def __init__(self,hp,atk):
self.hp = hp
self.atk = atk def damage(self,value):
self.hp -= value
print("受伤啦")
if self.hp <= 0:
self.__death() def attack(self,player):
print("打死你")
player.damage(self.atk) def __death(self):
print("死啦,播放动画") p01 = Player(100,50)
e01 = Enemy(60,10)
# 玩家打敌人
p01.attack(e01)
# p01.attack(e01)
e01.attack(p01)
内存图如下:
Python基础之面向对象2(封装)的更多相关文章
- python基础,函数,面向对象,模块练习
---恢复内容开始--- python基础,函数,面向对象,模块练习 1,简述python中基本数据类型中表示False的数据有哪些? # [] {} () None 0 2,位和字节的关系? # ...
- (转)Python成长之路【第九篇】:Python基础之面向对象
一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...
- Python 基础 四 面向对象杂谈
Python 基础 四 面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...
- 自学Python之路-Python基础+模块+面向对象+函数
自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python 1.1 自学Python1.1-简介 1.2 自学Python1.2-环境的 ...
- 二十. Python基础(20)--面向对象的基础
二十. Python基础(20)--面向对象的基础 1 ● 类/对象/实例化 类:具有相同属性.和方法的一类人/事/物 对象(实例): 具体的某一个人/事/物 实例化: 用类创建对象的过程→类名(参数 ...
- python基础(25):面向对象三大特性二(多态、封装)
1. 多态 1.1 什么是多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪. import abc class Animal(metaclass=abc.ABCMeta): #同一类事 ...
- python之路----面向对象的封装特性
封装 [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式. 广义上面向对象的封装 :代码的保护,面向对象的思想本身就是一种只让自己的对象能调用自己类中的方法 狭义上的封装 —— 面向对象的三大 ...
- Python高手之路【十一】python基础之面向对象
创建类和对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用. 类就是一个模板,模板里可以包含多个函数, ...
- 学习PYTHON之路, DAY 7 - PYTHON 基础 7 (面向对象基础)
面向对象三大特性 一.封装 封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容. 所以,在使用面向对象的封装特性时,需要: 将内容封装到某处 从某处调用被封装的内容 第一步:将内容 ...
- Day7 - Python基础7 面向对象编程进阶
Python之路,Day7 - 面向对象编程进阶 本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个 ...
随机推荐
- CentOS 7.2 Ubuntu 18部署Rsync + Lsyncd服务实现文件实时同步/备份
发送端配置: 一.配置密钥 1. 主/从服务器之间启用基于密钥的身份验证.登录发送端服务器并用 " ssh-keygen " 命令生成公共或私有的密钥. 2. 使用 " ...
- Mac本地搭建kubernetes环境
前言:之前在windows上面的虚拟机上面手工搭建了kubernetes集群,但是环境被破坏了,最近想要继续学习k8s,手工搭建太费事,所以选择了minikube,完全能够满足个人的需求,其实在Win ...
- mathJax基础语法-0基础开始,(这是网上抄来的如果有权限和版权问题联系本人处理,仅供学术参考)
- vertx的NetServer模块
启动 public synchronized void listen(Handler<NetSocket> handler, SocketAddress socketAddress, Ha ...
- php 获取用户的IP、地址、来源
js方法获取用户的 ip 和 地址 <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> ...
- Hive学习笔记 --Permission denied: user=anonymous, access=READ
执行select语句报错 Error: java.io.IOException: org.apache.hadoop.security.AccessControlException: Permissi ...
- VMware虚拟机安装WIN7
VMware在IT工作人员的学习之中,使用的较多,故聊一聊VMware中WIN7的安装: 第一步:安装VMware,这个软件百度就可以下载,但是是收费软件,注册码可以百度到. 第二步:VMware安装 ...
- Vue之展示PDF格式的文档
事实上有很多种在前端展示PDF格式文档的方法,小编也用过好多种,例如有<iframe>.<embed>和<object>这些标签,但是在Vue项目里,这些方法都不能 ...
- Zabbix (三)
一.zabbix支持的主要监控方式: zabbix主要Agent,Trapper,SNMP,JMX,IPMI这几种监控方式,本文章主要通过监控理论和实际操作测试等方式来简单介绍这几种方式的监控原理和优 ...
- mysql记录执行的SQL语句
show variables like "general_log%"; SET GLOBAL general_log = 'ON';SET GLOBAL general_log = ...