描述符

简介: 描述符

一个实现了 描述符协议 的类就是一个描述符。 什么是描述符协议:实现了 __get__()__set__()__delete__() 其中至少一个方法的类,就是一个描述符。

为何要使用描述符?

假想你正在给学校写一个成绩管理系统,并没有太多编码经验的你,可能会这样子写。

class Student:
    def __init__(self, name, math, chinese, english):
        self.name = name
        self.math = math
        self.chinese = chinese
        self.english = english
    def __repr__(self):
        return "<Student: {}, math:{}, chinese: {}, english:{}>".format(
                self.name, self.math, self.chinese, self.english
            )

看起来一切都很合理

>>> std1 = Student('小明', 76, 87, 68)
>>> std1
<Student: 小明, math:76, chinese: 87, english:68>

但是程序并不像人那么智能,不会自动根据使用场景判断数据的合法性,如果老师在录入成绩的时候,不小心录入了将成绩录成了负数,或者超过100,程序是无法感知的。

我们可以加入判断逻辑:

class Student:
    def __init__(self, name, math, chinese, english):
        self.name = name
        if 0 <= math <= 100:
            self.math = math
        else:
            raise ValueError("Valid value must be in [0, 100]")
        if 0 <= chinese <= 100:
            self.chinese = chinese
        else:
            raise ValueError("Valid value must be in [0, 100]")
        if 0 <= chinese <= 100:
            self.english = english
        else:
            raise ValueError("Valid value must be in [0, 100]")
    def __repr__(self):
        return "<Student: {}, math:{}, chinese: {}, english:{}>".format(
                self.name, self.math, self.chinese, self.english
            )

网络异常,图片无法展示
|

__init__里有太多的判断逻辑,很影响代码的可读性。我们学过 Property 特性,可以很好的应用在这里。于是将代码修改成如下,代码的可读性瞬间提升了不少:

class Student:
    def __init__(self, name, math, chinese, english):
        self.name = name
        self.math = math
        self.chinese = chinese
        self.english = english
    @property
    def math(self):
        return self._math
    @math.setter
    def math(self, value):
        if 0 <= value <= 100:
            self._math = value
        else:
            raise ValueError("Valid value must be in [0, 100]")
    @property
    def chinese(self):
        return self._chinese
    @chinese.setter
    def chinese(self, value):
        if 0 <= value <= 100:
            self._chinese = value
        else:
            raise ValueError("Valid value must be in [0, 100]")
    @property
    def english(self):
        return self._english
    @english.setter
    def english(self, value):
        if 0 <= value <= 100:
            self._english = value
        else:
            raise ValueError("Valid value must be in [0, 100]")
    def __repr__(self):
        return "<Student: {}, math:{}, chinese: {}, english:{}>".format(
                self.name, self.math, self.chinese, self.english
            )

程序还是一样的智能,非常好。

相关文章
|
7月前
|
缓存 Python
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
84 2
|
存储 安全 Linux
句柄是什么?一文带你了解!
今天又学习了一个装X概念——句柄,看字面意思,感觉跟某种器具有关,但实际上,这个词可不是用来打造家居用品的。
1076 0
|
Java
类型描述符
类型描述符
62 1
|
7月前
|
消息中间件 存储 缓存
Linux内存映射mmap
Linux内存映射mmap
84 0
UVC 基础学习(6):端点描述符介绍
今天带大家认识一下UVC端点描述符信息。
537 0
|
索引
UVC 基础学习(3):基础描述符介绍
UVC 基础学习(3):基础描述符介绍
593 0
|
物联网 Linux 开发者
复制文件描述符后新旧文件描述符特点|学习笔记
快速学习复制文件描述符后新旧文件描述符特点
|
Java Linux
[一]JavaIO之FileDescriptor文件描述符
FileDescriptor文件描述符 标准输入输出错误 文件描述符
1858 0
|
Shell Linux Unix