灵虚御风
醉饮千觞不知愁,忘川来生空余恨!

导航

 

22.封装 property装饰器 接口 抽象类 鸭子类型

1.封装

2.好处

3.语法

4.原理

5.访问私有属性的方法     property装饰器

6.计算属性

7.接口

8.抽象类

9.鸭子类型


1.封装:
    什么是封装,就是将复杂的丑陋的,隐私的细节隐藏到内部,对外提供简单的使用接口

    对外隐藏内部实现细节,并提供访问的接口

    为什么要封装?
        两个目的:
            1.为了保证 关键数据的安全性
            2.对外部隐藏实现细节,隔离复杂度

    什么时候应该封装?
        当有些数据不希望外界可以直接修改时,
        当有一些函数不希望给外界使用时

    如何使用 ?  __封装对象
        -  1.封装的基本使用.py


    被封装内容的特点:
        1.外部不能直接访问
        2.内部依然可以使用


学习了封装后就可以控制属性的权限

    在python只要两种权限,

    1.公开的.默认就是公开的

    2.私有的,只能由当前类自己使用
    在外界访问私有的内容

        属性虽然被封装了,但是还是需要使用的,在外界如何访问

        通过定义方法类完成对私有属性的修改和访问
            3.如何访问被封装的属性.py

  ```

这样一来我们可以在外界修改这个关键数据时,做一些限制
4.property装饰器

通过方法来修改或访问属性,本身没什么问题,但是这给对象的使用者带来了麻烦.

使用必须知道哪些是普通属性,哪些是私有属性,需要使用不同的方式来调用他们

property装饰就是为了使得调用方式一致

property 三个相关装饰器
    1.property 该装饰器用于获取属性的方法上
    2.@key.setter 该装饰器用在修改属性的方法上
    3.@key.deleter 该装饰器用于删除属性的方法上

ps:
    key 是被property 装饰的方法名称,也就是属性的名称
    内部会创建一个对象,变量名称就是函数名称
    所以在使用setter 和 deleter时,必须保证使用对象的名称去调用方法. 所以是 key.setter
    4.property装饰器.py

5.封装实现的原理
    就是在加载类的时候 ,把__替换成 _类名__
    Python 一般 不会强制 要求程序必须 怎么怎么的

封装
    对外部隐藏内部实现的细节,并提供访问的接口

    好处: 1.提高安全性 2.隔离复杂度

    语法:将要封装的属性或方法名称前加上双下划线
    访问被隐藏的属性:

​        提供用于访问和修改的方法
    使用property装饰器可以将一个方法伪装成普通顺属性,报纸属性之间调用方法一致

    封装的实现原理 ,替换变量名称

6.property 可以用来实现计算属性
    计算属性指的是:属性的值,不能直接获得,必须通过计算才能获取
    例如:正方形求面积 6.计算属性.py


7.接口
    接口是一组功能的集合体,但是接口中仅仅包含功能的名字,不包含具体的实现代码


接口的本质:一套协议标准,遵循这个标准的对象就可以被调用

接口的目的: 就是为了提高扩展性

    例: 7.接口的使用.py

在上述案例中,PC的代码一旦完成,后期无论什么样的设备 只要遵循了USB接口协议,都能够被电脑所调用

接口主要是方便了对象的使用者,降低使用者的 学习难度,只要学习一套使用方法,就可以以不变应万变

问题:

如果子类没有按照你的协议来设计,也没办法限制他,将导致代码无法运行

8.抽象类
    指的是包含抽象方法(没有函数体的方法)的类,

    作用:可以限制子类必须类中定义的抽象方法

最后:python一般不会限制你必须怎么写,作为一个优秀的程序员,就应该自觉遵守相关协议

所以有了鸭子类型这么一说:

如果这个对象长得像鸭子,走路像鸭子,那就他是鸭子
你只要保证你的类按照相关的协议类编写,也可以达到提高扩展性的目的
22.封装 property装饰器 接口 抽象类 鸭子类型
class Person:
    def __init__(self,id_number,name,age):
        self.__id_number = id_number
        self.name = name
        self.age = age

    def show_id(self):
        print(self.__id_number)

p = Person("111111111",'jack',29)
p.__id_number = "222"
# print(p.__id_number)
print(p.show_id())
"""
111111111
None
"""
1.封装的基本使用.py
class PC:
    def __init__(self,price,kind,color):
        self.price = price
        self.kind = kind
        self.color = color

    def open(self):
        print("接通电源")
        self.__check_device()
        print("载入内核")
        self.__start_services()
        print("初始化内核")
        self.__login()
        print("启动GUI")
    def __check_device(self):
        print("硬件检测1")
        print("硬件检测2")
        print("硬件检测3")
        print("硬件检测4")

    def __start_services(self):
        print("启动服务1")
        print("启动服务2")
        print("启动服务3")
        print("启动服务4")

    def  __login(self):
        print("login....")
        print("login....")
        print("login....")

pc1 = PC(20000,'苹果',"红色")
pc1.open()
# pc1.login()
"""
接通电源
硬件检测1
硬件检测2
硬件检测3
硬件检测4
载入内核
启动服务1
启动服务2
启动服务3
启动服务4
初始化内核
login....
login....
login....
启动GUI

"""
2.封装方法.py
"""
这是一个下载器类,需要提供一个缓存大小这样的属性
缓存大小不能超过内存限制

"""
class Downloader:
    def __init__(self,filename,url,buffer_size):
        self.filename = filename
        self.url = url
        self.__buffer_size = buffer_size

    def start_download(self):
        if self.__buffer_size <= 1024 * 1024:
            print("开始下载....")
            print("当前缓冲器大小",self.__buffer_size)

        else:
            print("内存炸了")
    def set_buffer_size(self,size):
        # 可以在方法中添加额外的逻辑
        if not type(size) == int:
            print("大哥,缓冲区大小必须是整型")
        else:
            print("缓冲器大小修改成功")
            self.__buffer_size = size
    def get_buffer_size(self):
        return self.__buffer_size


d = Downloader("葫芦娃","http://www.baidu.com",1024*1024)

# 通过函数去修改内部封装的属性
d.set_buffer_size(1024*512)

# 通过函数访问内部封装的属性
print(d.get_buffer_size())
print(d.filename)
d.start_download()

"""
缓冲器大小修改成功
524288
葫芦娃
开始下载....
当前缓冲器大小 524288

"""
3.如何访问被封装的属性.py
class A:
    def __init__(self,name,key):
        self.__name = name
        self.__key = key

    @property
    def key(self):
        return self.__key

    @key.setter
    def key(self,new_key):
        if new_key <= 100:
            self.__key = new_key
        else:
            print("key 必须小于等于100")

    @key.deleter
    def key(self):
        print("不允许删除该属性")
        del self.__key

    # @property
    # def name(self):
    #     return self.__name
    #
    # @name.setter
    # def name(self, new_name):
    #     self.__name = new_name

a = A('jack',123)
# print(a.name)
print(a.key) # 123
a.key = 321 # key 必须小于等于100
print(a.key) # 123

# del a.key
# print(a.key)

a.name = "xx"
print(a.name) # xx
4.property装饰器.py
class A:
    def __init__(self,key):
        self.__key = key

    @property
    def key(self):
        return self.__key

    @key.deleter
    def key(self):
        del self.__key


a = A("123")
print(a.key) # 123
# del a.key
# print(a.key)

print(a._A__key)# 123

a.__name = 1
print(a.__dict__) # {'_A__key': '123', '__name': 1}

print("__key".replace("__","_A__")) # _A__key
5.封装的实现原理.py
class Square:
    def __init__(self,width):
        self.width = width
        # self.area = self.width * self.width

    @property
    def area(self):
        return self.width * self.width


s = Square(10)
print(s.area) #
# 练习: 定义一个类叫做person
# 包含三个属性 身高 体重   BMI
# BMI的值需要通过计算得来 公式   体重 / 身高的平方
class Person:
    def __init__(self,high,wight):
        self.high = high
        self.wight = wight

    @property
    def BMI(self):
        return self.wight / (self.high ** 2)
p = Person(180,85)
print(p.BMI)# 0.002623456790123457
6.计算属性.py
class USB:
    def open(self):
        pass

    def close(self):
        pass

    def  read(self):
        pass

    def write(self):
        pass

class Mouse(USB):
    def open(self):
        print("鼠标开机.....")

    def close(self):
        print("鼠标关机了...")

    def read(self):
        print("获取了光标位置....")

    def write(self):
        print("鼠标不支持写入....")


def pc(usb_device):
    usb_device.open()
    usb_device.read()
    usb_device.write()
    usb_device.close()

m = Mouse()
# 将鼠标传给电脑
pc(m)

class KeyBoard(USB):
    def open(self):
        print("键盘开机.....")

    def close(self):
        print("键盘关机了...")

    def read(self):
        print("获取了按键字符....")

    def write(self):
        print("可以写入灯光颜色....")

# 来了一个键盘对象
k = KeyBoard()
pc(k)


class UDisk(USB):

    def open(self):
        print("U盘启动了...")

    def close(self):
        print("U盘关闭了...")

    def read(self):
        print("读出数据")

    def write(self):
        print("写入数据")

u = UDisk()

pc(u)
7.接口的使用.py
""""""
"""
abc 不是随意取的 而是单词的缩写
abstract class
翻译为抽象类
抽象类的定义 :
类中包含 没有函数体的方法

"""
import abc
class AClass(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def run(self):
        pass
    @abc.abstractmethod
    def run1(self):
        pass

class B(AClass):
    def run(self):
        print("runnnnnnnn....")
    def run1(self):
        print("run111111")
b = B()
print(b.run)
"""
<bound method B.run of <__main__.B object at 0x0000025B2DB25438>>
"""
8.abc模块的使用.py
posted on 2022-03-25 15:57  没有如果,只看将来  阅读(14)  评论(0编辑  收藏  举报