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 == "1":
            self.__input_students()
        elif number == "2":
            pass
        elif number == "3":
            pass
        elif number == "4":
            pass
        elif number == "5":
            pass

    def main(self):
        """
            界面入口方法
        :return:
        """
        while True:
            self.__display_menu()
            self.__select_menu()

view = StudentManagerView()
view.main()

    

    

原文地址:https://www.cnblogs.com/yuxiangyang/p/10712430.html

时间: 2024-10-10 11:02:46

Python基础之面向对象2(封装)的相关文章

Day6 - Python基础6 面向对象编程

Python之路,Day6 - 面向对象学习 本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢? 你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色 1 2 3 4 5 6 7 8 9 10 11

Python基础09 面向对象的进一步拓展

Python基础09 面向对象的进一步拓展 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们熟悉了对象和类的基本概念.我们将进一步拓展,以便能实际运用对象和类. 调用类的其它信息 上一讲中提到,在定义方法时,必须有self这一参数.这个参数表示某个对象.对象拥有类的所有性质,那么我们可以通过self,调用类属性. class Human(object): laugh = 'hahahaha' def show_laugh(

Python基础6-1 面向对象编程

概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." 面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处. while True:     if cpu利用率 > 90%:         #发送邮件提醒         连接邮箱服务器         发送邮件     

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

面向对象三大特性 一.封装 封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容. 所以,在使用面向对象的封装特性时,需要: 将内容封装到某处 从某处调用被封装的内容 第一步:将内容封装到某处 self 是一个形式参数,当执行 obj1 = Foo('wupeiqi', 18 ) 时,self 等于 obj1 当执行 obj2 = Foo('alex', 78 ) 时,self 等于 obj2 所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都有 name

Python基础08 面向对象的基本概念

Python基础 面向对象的基本概念 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 谢谢逆水寒龙,topmad和Liqing纠错 Python使用类(class)和对象(object),进行面向对象(object-oriented programming,简称OOP)的编程. 面向对象的最主要目的是提高程序的重复使用性.我们这么早切入面向对象编程的原因是,Python的整个概念是基于对象的.了解OOP是进一步学习Python

Python基础-第六天-面向对象编程

本篇内容 1.面向对象编程介绍 2.类的定义及各部分的介绍 3.属性 4.方法 5.面向对象的特性-封装 6.面向对象的特性-继承 7.面向对象的特性-多态 8.新式类和经典类 一.面向对象编程介绍 1.编程的原则 无论用什么编程范式来编程都要记住的原则是,避免写重复代码,代码要易扩展.一定要遵循可读性好.易扩展的原则. 2.面向对象编程(Object-Oriented Programming)介绍 OOP编程的主要作用是使代码修改和扩展变的更容易: 面向对象编程是利用类和对象来帮助我们实现功能

Python基础之面向对象(初级篇)

概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强...” 面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处. while True: if cpu利用率 > 90%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 硬盘使用空间 > 90%: #发送邮件提醒 连接邮箱服务器 发

python3 速查参考- python基础 8 -&gt; 面向对象基础:类的创建与基础使用,类属性,property、类方法、静态方法、常用知识点概念(封装、继承等等见下一章)

基础概念 1.速查笔记: #-- 最普通的类 class C1(C2, C3): spam = 42 # 数据属性 def __init__(self, name): # 函数属性:构造函数 self.name = name def __del__(self): # 函数属性:析构函数 print("goodbey ", self.name) I1 = C1('bob') #-- Python的类没有基于参数的函数重载 class FirstClass: def test(self,

Python 基础之面向对象初识与类的封装

一: 面向对象类的初识#(1) 类的定义#三种方式:#1.class MyClass:    pass #2.推荐class MyClass():    pass #3.class MyClass(object):    pass#(2) 类的实例化class MyClass():    pass#类的实例化,实例化对象obj = MyClass() #obj 就是一个对象#(3)类的基本结构只有成员方法和成员属性对象.属性  对象.方法()#例:class MyClass():    #成员属