封装与封装设计思想

封装语法

数据角度:将一些基本的数据类型复合成了自定义类

优点

1、建立与数据与数据之间的连接
2、代码可读性强(通过类可以查看到对象的属性或方法)

缺点

从行为角度理解:数据(属性、方法)会暴露,可以任意操作

行为角度:类外提供必要的功能,隐藏实现的细节

优点

使用者不用去了解内部的实现细节,只需要关注对外提供的功能。

私有成员

demo1:私有后,不能直接访问

# 私有成员

class Student:
    def __init__(self, name, age, score):
        self.name = name
        self.__age = age    # 私有变量
        self.score = score

    # 私有成员可以在类内直接访问(推荐)
    def __show_infos(self):
        print('姓名:%s,年龄:%d,成绩:%d' % (
            self.name, self.__age, self.score))



# 在类外访问
stu = Student('YY', 18, 66)
# print(stu.__age)   # AttributeError

# 查看实例对象的变量字典
print(stu.__dict__)

# python的类中没有绝对的私有化,只是做了【屏蔽】
print(stu._Student__age)  # 不推荐(私有化,强行访问)

# 通过实例方法访问
# stu.show_infos()   # 私有方法在类外不能直接访问

stu._Student__show_infos()   # 不推荐【‘防君子不防小人’】


# 问题:以上方式在类外不能直接访问.如果要访问?

demo2:不符合面向对象

# 问题:以上方式在类外不能直接访问.如果要访问?
# 措施:
#  1、私有化实例变量
# 2、提供2个公开的方法(读、写方法)

class Student:
    def __init__(self, name, age, money):
        self.name = name
        self.age = age
        self.__money = money   # 私有变量

    def get_money(self):       # 读取方法
        return self.__money

    def set_money(self, value):  # 写入方法
        self.__money = value

stu = Student('老毕', 18, 10000)
# print(stu._Student__money)
# stu._Student__money += 100
# print(stu._Student__money)

# 读取
print(stu.get_money())
# 修改
stu.set_money(11000)
print(stu.get_money())

# 问题:实例化对象无法查看到当前自身的属性,不符合面向对象的语法。

demo3:属性引入

# 私有成员
# 问题:实例化对象无法查看到当前自身的属性,不符合面向对象的语法。
# 措施:
#   1、私有化实例变量
#  2、提供2个公开的方法(读、写方法)

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

    def get_money(self):       # 读取方法
        return self.__money

    def set_money(self, value):  # 写入方法
        self.__money = value

stu = Student('老毕', 18, 10000)
print(stu.__dict__)

# 读取
print(stu.get_money())
# 修改
stu.set_money(11000)
print(stu.get_money())

# 问题:为了实例对象多添加一个属性,不是解决咱们的问题。

demo4:属性添加 property作用

property作用:拦截将对变量的操作拦截给了对方法的操作!why?变量无法给予逻辑,方法可以。。

# 私有成员
# 问题:为了实例对象多添加一个属性,不是解决咱们的问题。
数据修改不符合规范,超出正常范围
# 措施:
#1、创建实例变量
#2、提供2个公开的方法(读、写方法)
#3、创建类变量存储property对象
# 目的:
#   实现了对实例变量的保护,符合Python面向对象的语法

# 在为实例对象添加money属性时,调用set_money方法,为实例对象添加私有属性money
class Student:
    def __init__(self, name, age, money):
        self.name = name
        self.age = age
        self.money = money      #程序执行的是property那行代码
        # self.set_money(money)

    def get_money(self):       # 读取方法
        return self.__money

    def set_money(self, value):  # 写入方法
		if 0 <= value <= 20000:   # 数据有效性验证
            self .__money = value
        else:
            raise Exception('数据超过正常范围')  # 抛出异常

    # 添加实例变量money时建立set_money的联系(类变量)
    # 将实例变量修改为了私有变量
    money = property(get_money, set_money)
    # print('类变量:', money)

stu = Student('老毕', 18, 10000)
print(stu.__dict__)         

# 读取
print(stu.get_money())

# 访问类变量
print(Student.money)
print(stu.money)

# 修改
stu.set_money(1100000)
print(stu.get_money())

# 问题:现在读写方法访问太多麻烦,采用:实例对象.实例成员

demo5:标准属性:保护数据

针对于demo4而言,不用类变量

# 问题:现在读写方法访问太多麻烦,采用:实例对象.实例成员
# 措施:
#1、创建实例变量
#2、提供2个公开的方法(读、写方法)
#3、使用@property修饰读取方法 使用@属性名.setter修改写入方法
# 目的:
#   实现了对实例变量的保护,符合Python面向对象的语法, 实现数据有效性验证

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

    @property  #创建property对象 自动绑定下面方法(读取方法)
    # 方法名必须和属性名称相同 不能叫get_money了 此处money可以理解为存储property对象的变量
    def money(self):       # 读取方法
        return self.__money

    @money.setter  #给property对象绑定下面方法(写入方法) 同样的方法名要叫money
    def money(self, value):  # 写入方法
        if 0 <= value <= 20000:   # 数据有效性验证
            self.__money = value
        else:
            raise Exception('数据超过正常范围')  # 抛出异常

    # money = property(get_money, set_money)

stu = Student('老毕', 18, 10000)
print(stu.__dict__)

# 读取(调用了读取方法)
print(stu.money)

# 修改(调用了写入方法)
stu.money = 12000
print(stu.money)

属性@property总结

常见写法

可读可写

class 类名([父类]):
    def __init__(self, 参数):
        self.属性名 = 参数
        ...

    @property
    def 属性名(self):    # 读取方法(返回私有变量)
        return self.__属性名

    @属性名.setter
    def 属性名(self, value):    # 写入(修改:第1次实例化为实例对象添加对应属性时)
        # 数据有效性验证
        self.__属性名 = value

只读

class 类名([父类]):
    def __init__(self, 参数):
        self.__属性名 = 参数
        ...

    @property
    def 属性名(self):    # 读取方法(返回私有变量)
        return self.__属性名

只写

class 类名([父类]):
    def __init__(self, 参数):
        self.属性名 = 参数
        ...

    def 属性名(self, value):    # 写入(修改:第1次实例化为实例对象添加对应属性时)
        # 数据有效性验证
        self.__属性名 = value

    属性名 = property(None, 属性名)

封装设计思想

分而治之 变则疏之
高内聚 低耦合

分而治之
将一个大需求分解为许多类,每个类处理一个独立的功能
变则梳之
变化的地方独立封装,避免影响其他类
高内聚
类中哥哥方法都在完成一项任务
类的职责要单一
低耦合
类与类的关联性与依赖度要低
每个类独立,让一个类的改变,尽少影响其他类

设计思想

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值