一、封装定义:

  

 二、作用

  

三、私有成员:

  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(封装)的更多相关文章

  1. python基础,函数,面向对象,模块练习

    ---恢复内容开始--- python基础,函数,面向对象,模块练习 1,简述python中基本数据类型中表示False的数据有哪些? #  [] {} () None 0 2,位和字节的关系? # ...

  2. (转)Python成长之路【第九篇】:Python基础之面向对象

    一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...

  3. Python 基础 四 面向对象杂谈

    Python 基础  四  面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...

  4. 自学Python之路-Python基础+模块+面向对象+函数

    自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python    1.1 自学Python1.1-简介    1.2 自学Python1.2-环境的 ...

  5. 二十. Python基础(20)--面向对象的基础

    二十. Python基础(20)--面向对象的基础 1 ● 类/对象/实例化 类:具有相同属性.和方法的一类人/事/物 对象(实例): 具体的某一个人/事/物 实例化: 用类创建对象的过程→类名(参数 ...

  6. python基础(25):面向对象三大特性二(多态、封装)

    1. 多态 1.1 什么是多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪. import abc class Animal(metaclass=abc.ABCMeta): #同一类事 ...

  7. python之路----面向对象的封装特性

    封装 [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式. 广义上面向对象的封装 :代码的保护,面向对象的思想本身就是一种只让自己的对象能调用自己类中的方法 狭义上的封装 —— 面向对象的三大 ...

  8. Python高手之路【十一】python基础之面向对象

    创建类和对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用. 类就是一个模板,模板里可以包含多个函数, ...

  9. 学习PYTHON之路, DAY 7 - PYTHON 基础 7 (面向对象基础)

    面向对象三大特性 一.封装 封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容. 所以,在使用面向对象的封装特性时,需要: 将内容封装到某处 从某处调用被封装的内容 第一步:将内容 ...

  10. Day7 - Python基础7 面向对象编程进阶

    Python之路,Day7 - 面向对象编程进阶   本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个 ...

随机推荐

  1. C++入门篇十一

    单例对象:为了让类只有一个实例,实例不需要自己释放掉 不管创建多少个实例对象进行访问,访问的都是同一个值 #include "pch.h" #include <iostrea ...

  2. JS 冷知识,运行机制

    数组取最小.最大值 var a=[1,2,3,5]; alert(Math.max.apply(null, a));//最大值 alert(Math.min.apply(null, a));//最小值 ...

  3. 主席树——求区间第k个不同的数字(向右密集hdu5919)

    和向左密集比起来向右密集只需要进行小小的额修改,就是更新的时候从右往左更新.. 自己写的被卡死时间.不知道怎么回事,和网上博客的没啥区别.. /* 给定一个n个数的序列a 每次询问区间[l,r],求出 ...

  4. 用 pdf.js兼容部分安卓显示PDF在线预览 时,a标签直接链接参数文件不能含中文的解决办法

    例子: 项目部署在 Tomcat 上的: <a href="../generic/web/viewer.html?file=doc/register/要显示的文件.pdf" ...

  5. android新窗口以及传值

    1,新建一个activity,如Activity2,在清单文件AndroidManifest.xml 中 application节点中 增加一个新窗体: ................. </ ...

  6. RxJS操作符(三)

    一.过滤类操作符:debounce, debounceTime 跟时间相关的过滤 debounceTime自动完成:性能,避免每次请求都往出发 ); debounce中间传入Observable co ...

  7. hiper工具查看页面加载时间

    先需要下载 cnpm i hiper -g # 当我们省略协议头时,默认会在url前添加`https://` # 最简单的用法 hiper baidu.com # 如何url中含有任何参数,请使用双引 ...

  8. docker异常问题解决

    解决方法: 发现这个问题出现的时候,并不是所有的docker都会出现,只影响某个docker 停下:docker stop app-6019-bonus 再起来:docker start app-60 ...

  9. zabbix-tomcat监控

    安装tomcat 1安装jdk # yum install lrzsz -y #tar xvf jdk # ln -sv /usr/local/src/jdk1..0_79/ /usr/local/j ...

  10. 在ideaUI中建立maven项目

    1.新建New 注意:第一次创建maven项目需要在有网情况下进行 2.可以看见我们建立的项目了