了解一下 Python 的描述符

简介: 了解一下 Python 的描述符

类里的三个属性,math、chinese、english,都使用了 Property 对属性的合法性进行了有效控制。功能上,没有问题,但就是太啰嗦了,三个变量的合法性逻辑都是一样的,只要大于0,小于100 就可以,代码重复率太高了,这里三个成绩还好,但假设还有地理、生物、历史、化学等十几门的成绩呢?

了解一下 Python 的描述符。

一个实现了 描述符协议 的类就是一个描述符。

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

__get__: 用于访问属性。它返回属性的值,若属性不存在、不合法等都可以抛出对应的异常。
__set__:将在属性分配操作中调用。不会返回任何内容。
__delete__:控制删除操作。不会返回内容。
下面的Score 类是一个描述器,当从 Student 的实例访问 math、chinese、english这三个属性的时候,都会经过 Score 类里的三个特殊的方法。这里的 Score 避免了 使用Property 出现大量的代码无法复用的尴尬。
class Score:

def __init__(self, default=0):
    self._score = default

def __set__(self, instance, value):
    if not isinstance(value, int):
        raise TypeError('Score must be integer')
    if not 0 <= value <= 100:
        raise ValueError('Valid value must be in [0, 100]')

    self._score = value

def __get__(self, instance, owner):
    return self._score

def __delete__(self):
    del self._score

class Student:

math = Score(0)
chinese = Score(0)
english = Score(0)

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
        )

实现的效果和前面的一样,可以对数据的合法性进行有效控制(字段类型、数值区间等)

image.png

参考 https://juejin.im/post/5cc4fbc0f265da0380437706

描述器应用---验证参数类型

class Typed:

def __init__(self, key, expected_type):  # 构造函数接收所传入的参数和参数类型
    self.key = key
    self.expected_type = expected_type

def __get__(self, instance, owner):
    print('get方法')
    return instance.__dict__[self.key]  # 从底层字典获取值

def __set__(self, instance, value):
    print('set方法')
    if not isinstance(value, self.expected_type):  # 类型判断
        raise TypeError('%s 传入的类型不是%s' % (self.key, self.expected_type)) # 格式化抛出异常
    instance.__dict__[self.key] = value # 修改底层字典

def __delete__(self, instance):
    print('delete方法')
    instance.__dict__.pop(self.key)

class People:

name = Typed('name', str)  # p1.__set__()  self.__set__(),触发描述符__set__方法,设置参数类型传给构造函数
age = Typed('age', int)  # p1.__set__()  self.__set__()
salary = Typed('salary', float)  # p1.__set__()  self.__set__()
def __init__(self, name, age, salary):
    self.name = name
    self.age = age
    self.salary = salary

p1=People('alex','13',13.3)#类型有误,报错

p1 = People('alex', 13, 13.3)
print(p1.__dict__)
print(p1.name)
p1.name = 'egon'
print(p1.__dict__)
del p1.name
print(p1.__dict__)

print(p1.name) # 相应的键值对已在底层字典中删除了,报错

相关文章
|
7月前
|
缓存 Python
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
什么是Python中的描述符(Descriptor)?如何实现一个描述符?
84 2
|
安全 数据安全/隐私保护 Python
Python中的描述符:理解并利用其强大的功能
Python是一种动态类型语言,这意味着我们可以在运行时更改对象的结构,例如添加或删除属性。然而,这种灵活性有时可能会导致问题,例如我们可能无意中改变了一个属性的值,或者误用了一个应该是只读的属性。为了解决这些问题,Python提供了一个强大的特性:描述符。
|
Python
Python描述符(__get__和__set__和__delete__)
Python描述符(__get__和__set__和__delete__)
116 0
|
数据安全/隐私保护 Python
python描述符学习
目录 一、对象属性的访问控制 二、描述符基本理解 三、基本使用 四、使用描述符完成property、classmethod、staticmethod自定义实现 1、property的自定义实现 2、classmethod的自定义实现 3、关于实例方法的思考 4、实例方法的自定义实现 5、静态方法的自定义实现 五、总结 一、对象属性的访问控制 看一下这个例子,我们创建一个学生类,提供名字和年龄的属性,然后实例化一个对象,并显示他的信息。
|
Python 程序员 容器
|
15天前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
14天前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
3天前
|
Unix Linux 程序员
[oeasy]python053_学编程为什么从hello_world_开始
视频介绍了“Hello World”程序的由来及其在编程中的重要性。从贝尔实验室诞生的Unix系统和C语言说起,讲述了“Hello World”作为经典示例的起源和流传过程。文章还探讨了C语言对其他编程语言的影响,以及它在系统编程中的地位。最后总结了“Hello World”、print、小括号和双引号等编程概念的来源。
97 80
|
21天前
|
存储 索引 Python
Python编程数据结构的深入理解
深入理解 Python 中的数据结构是提高编程能力的重要途径。通过合理选择和使用数据结构,可以提高程序的效率和质量
133 59
下一篇
DataWorks