封装及其相关

本文介绍了Python中的封装概念,包括其与隐藏的区别、封装的好处,如提高安全性、隔离复杂度。文章详细讲解了Python中如何通过双下划线创建私有属性,以及访问器、设置器的使用。此外,还探讨了`property`装饰器的作用,以及如何通过抽象类和接口来增强程序的扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

封装
    字面意思 把什么东西装到容器 在封闭起来
    与隐藏有相似之处 但不是单纯的隐藏
官方解释:对外部隐藏实现细节,并提供简单的使用接口

封装的好处
1.提高安全性  封装关键数据来实现
2.隔离复杂度  封装一些内部的实现逻辑(方法)来实现

python中的属性访问权限
1.公开的(默认) 在任何地方都能访问到
2.私有的  仅在类内部可以使用

如何封装:
    使用特殊语法:给要隐藏的变量名称前面加上两个下划线 __ 使其变成私有的

class Person:

    def __init__(self,name,sex,age,id_card):
        self.name = name
        self.age = age
        self.sex = sex
        self.__id_card = id_card

    def say_hi(self):
        print("hello my name is %s age %s sex %s id %s" %
              (self.name,self.age,self.sex,self.__id_card)) # 内部可以访问

p1 = Person("xxx","man",30,"12121121212121X")
p1.say_hi()
print(p1.__id_card) #外部无法访问私有的内容

# 封装方法
# 场景 一些方法的存在是为了 完成其他的功能  这些方法就不应该提供给外界 例如发动机中的 打火这个功能
# 当一个方法中的代码 太多时  我们需要将其拆分为不同的小函数  这个小函数不应该提供给外界

class PC:
    def boot(self):
        self.__read_rom()
        self.__boot_bios()
        self.__read_opt()
        self.__boot_gui()
        print("电脑启动成功!")
    def __read_rom(self):
        print("读取rom中的数据")
    def __boot_bios(self):
        print("启动BIOS系统")
    def __read_opt(self):
        print("读取并执行操作系统命令")
    def __boot_gui(self):
        print("启动用户界面")

p1 = PC()
p1.boot()

访问器与设置器:

私有属性  外界完全无法使用 那就没有意义
我们可以定义访问方法 和设置方法 也称之为访问器 和 设置器
1.提供对私有属性的访问修改
2.增加额外的判断逻辑

class Person:
    def __init__(self,name,sex,age,id_card):
        self.name = name
        self.age = age
        self.sex = sex
        self.__id_card = id_card

    def say_hi(self):
        print("hello my name is %s age %s sex %s id %s" %
              (self.name,self.age,self.sex,self.__id_card)) # 内部可以访问

    # 访问器
    def get_id_card(self,pwd):
        if pwd == "123321":
            return self.__id_card
        else:
            print("没有访问权限!")

    # 设置器
    def set_id_card(self,new_id):
        if len(new_id) == 17 or len(new_id) == 18:
            self.__id_card = new_id
        else:
            print("身份证格式错误!")

p1 = Person("xx","man",29,"1212617637821673X")
# print(p1.get_id_card("123321X"))

p1.set_id_card("11111111111111111")
print(p1.get_id_card("123321"))

print(p1.name)
print(p1.get_id_card("123321"))

p1.name = "xxx"
p1.set_id_card("12121212121212121")

property装饰器:
问题:
    访问和修改私有属性 的写法 与 普通属性的写法不一致
    对于使用而言更复杂了

使用property装饰器可以将一个方法伪装成一个普通属性
这样对于使用者而言 使用方式一致了
@property弊端是方法不能增加额外的参数只能有一个self

访问器
@property  用点来访问属性时触发  p1.id_card
设置器
@属性名称.setter   用点来设置属性时触发 p1.id_card = "12345"
删除器
@属性名称.deleter  用del 删除属性时触发 del p1.id_card

class Person:
    def __init__(self,name,id_card):
        self.name = name
        self.__id_card = id_card

    @property
    def id_card(self):
        return self.__id_card

    @id_card.setter
    def id_card(self,new_id):
        self.__id_card = new_id

    @id_card.deleter
    def id_card(self):
        print("不好了  没睡好")
        self.__dict__.pop("_Person__id_card")

p1 = Person("bgon","123321")
# print(p1.name)
# print(p1.id_card) #访问私有属性
#
# p1.id_card = "12345" #设置私有属性
# print(p1.id_card)

print(p1.__dict__)

del p1.id_card # 删除私有属性

python封装的原理:

python是通过变形的方式 来完成私有化操作
具体:把双下划线开头的名字 在名字前添加_类名

发生变形操作是在定义阶段就发生了并且只发生一次

默认情况下  子类是无论是类内部还是外部都不能访问父类的私有属性的  当然你可以强行访问

class Person:
    def __init__(self,id):
        self.__id = id
        self.name = "bgon"

    def __test(self):
        pass

# p1 = Person("123")
# print(p1.__dict__)
# print(p1.__id)
# print(Person.__dict__)
Person.__a = 1
print(Person.__dict__)

interface 接口
是一组功能集合体

好处:用于提高程序的扩展性
接口用于定义一组功能 ,后续的程序只要按照接口来进行实现 就能被使用 
例如电脑的USB接口  只要你的设备按照USB接口规定的来实现 就能被电脑使用
可以将接口理解为是一套规范

class USBInterface:

    def boot(self):
        pass

    def close(self):
        pass

class Mouse(USBInterface):

    def boot(self):
        print("鼠标启动了")
    def close(self):
        print("鼠标关闭了")

class KeyBoard(USBInterface):
    def boot(self):
        print("键盘启动了")
    def close(self):
        print("键盘关闭了")

m1 = Mouse()
k1 = KeyBoard()

m1.boot()
m1.close()

k1.boot()
k1.close()

抽象类:

问题:使用class来模拟接口的问题是 不能强行限制子类必须实现接口的方法

抽象类:
    抽象在这里指的是  不具体 不清晰  看不懂
    如果一个方法 没有实现体 那么这个方法就可以称之为抽象方法
    如果一个类中存在抽象方法 那么这个类也是抽象的
    反过来说 只要有方法没有实现体 那么这个类就是抽象的

作用:
    抽象类 也是用于提高扩展性的  与接口相似的是 也可以作为一套规范
    比接口强大的地方在与 可以强行限制 子类必须实现父类中声明的方法

特点:
    抽象类无法直接实例化  只能由子类继承之后 覆盖所有的抽象方法  才能实例化对象

import abc
# abstructclass
class Computer(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def boot(self):
        pass

    @abc.abstractmethod
    def close(self):
        pass
    #
    @abc.abstractmethod
    def working(self):
        pass

class NoteBook(Computer):

    def boot(self):
        print("笔记本开机啦")

    def close(self):
        print("笔记本关机啦")

    def working(self):
        print("笔记本正在计算")

n1 = NoteBook()
n1.boot()
n1.working()
n1.close()

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值