描述符介绍

描述符本质就是一个新式类,在这个新式类中,至少要实现了__get__()__set__()__delete__()中的一个。这也被称为描述符协议。

class Myclass(object): 

    def __get__(self, instance, owner):
'''调用一个属性时触发'''
pass def __set__(self, instance, value):
'''为一个属性赋值时触发'''
pass def __delete__(self, instance):
'''使用del删除属性时触发'''
pass

描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中)

数据描述符

至少实现了__get__()__set__()

class Myclass(object):

    def __set__(self, instance, value):
print('set') def __get__(self, instance, owner):
print('get')

非数据描述符

没有实现__set__()

class Myclass(object):

    def __get__(self, instance, owner):
print('get')

注1:必须把描述符定义成这个类的类属性,不能为定义到构造函数中

注2:要严格遵循该优先级,优先级由高到底分别是

  1. 类属性
  2. 数据描述符
  3. 实例属性
  4. 非数据描述符
  5. 找不到的属性触发 __getattr__()

例1:利用描述符实现参数类型检测

class Typed(object):

    def __init__(self, key, exc_type):
self.key = key
self.exc_type = exc_type def __get__(self, instance, owner):
return instance.__dict__[self.key] def __set__(self, instance, value):
# 先判断类型是否为期望类型,如果不是则报错
if not isinstance(value, self.exc_type):
raise TypeError
instance.__dict__[self.key] = value def __delete__(self, instance):
instance.__dict__.pop(self.key) class Person(object):
name = Typed('name', str)
age = Typed('age', int) def __init__(name, age):
self.name = name
self.age = age

例2:使用描述符自定制property

class Lazyproperty(object):

    def __init__(self, func):
self.func = func def __get__(self, instance, owner):
'''使用该方法实现非数据描述符'''
# 当使用类调用属性时,返回自身
if not isinstance:
return self
ret = self.func(instance)
# 如果该属性计算过程较为复杂,可以为实例设置属性,以后就不用重复计算了
# 原因是因为非数据描述符优先级低于实例属性,下次调用的时候会优先从实例属性字典中查找
# 而不会再次调用本方法重复计算
setattr(instance, self.func.__name__, ret)
return ret class Room(object): def __init__(self, name, width, length):
self.name = name
self.width = width
self.length = length @Lazyproperty # 这一步相当于定义了一个类属性 -> area = Lazyproperty(area)
def area(self):
return self.width * self.length

一文掌握 Python 的描述符协议的更多相关文章

  1. 杂项之python描述符协议

    杂项之python描述符协议 本节内容 由来 描述符协议概念 类的静态方法及类方法实现原理 类作为装饰器使用 1. 由来 闲来无事去看了看django中的内置分页方法,发现里面用到了类作为装饰器来使用 ...

  2. Iterator Protocol - Python 描述符协议

    Iterator Protocol - Python 描述符协议 先看几个有关概念, iterator 迭代器, 一个实现了无参数的 __next__ 方法, 并返回 '序列'中下一个元素,在没有更多 ...

  3. Descriptor - Python 描述符协议

    描述符(descriptor) descriptor 是一个实现了 __get__. __set__ 和 __delete__ 特殊方法中的一个或多个的. 与 descriptor 有关的几个名词解释 ...

  4. python理解描述符(descriptor)

    Descriptor基础 python中的描述符可以用来定义触发自动执行的代码,它像是一个对象属性操作(访问.赋值.删除)的代理类一样.前面介绍过的property是描述符的一种. 大致流程是这样的: ...

  5. Python属性描述符(一)

    描述符是对多个属性运用相同存取逻辑的一种方式,,是实现了特性协议的类,这个协议包括了__get__.__set__和__delete__方法.property类实现了完整的描述符协议.通常,可以只实现 ...

  6. python数据描述符

    Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题苦恼的朋友提 ...

  7. 【python】描述符descriptor

    开始看官方文档,各种看不懂,只看到一句Properties, bound and unbound methods, static methods, and class methods are all ...

  8. python Descriptor (描述符)

    简介: python 描述符是新式类(继承自object)中的语言协议,基于描述符可以提供更佳优雅的解决方案. python的classmethod, staticmethod, property都是 ...

  9. python - 数据描述符(class 内置 get/set/delete方法 )

    数据描述符(class 内置 get/set/del方法 ): # 什么是描述符 # 官方的定义:描述符是一种具有“捆绑行为”的对象属性.访问(获取.设置和删除)它的属性时,实际是调用特殊的方法(_g ...

随机推荐

  1. win10让人愤怒的磁盘占用100%问题

    升级win10以后其他还好.但是系统经常响应非常非常慢,后来观察发现每次非常卡的时候我的磁盘占用就是100%的. 我是技嘉的B85主板. 1盘是128g的东芝SSD(GPT), 2盘是WD的3TB H ...

  2. 流程图(flowchart)语法学习

    创建流程图需要选择语言: mermaid流程中的代码包裹graph 这里写顺序end流程图方向:从上到下(TB),从下到上(BT),从左到右(LR),从右到左(RL) TB - 从上到下TD - 自上 ...

  3. Go语言核心36讲(Go语言实战与应用十四)--学习笔记

    36 | unicode与字符编码 在开始今天的内容之前,我先来做一个简单的总结. Go 语言经典知识总结 在数据类型方面有: 基于底层数组的切片: 用来传递数据的通道: 作为一等类型的函数: 可实现 ...

  4. 一个Java发送邮件的案例

    经常有些要发送邮件的需求,但是去网上拷代码老是拷不到能直接运行的,还经常要去以前的项目里面拷,今天直接发出来算了,免得每次都要去别的项目拷. (只支持发送简单的文本文件,发附件的稍微复杂一丢丢,这里就 ...

  5. Codeforces 338E - Optimize!(Hall 定理+线段树)

    题面传送门 首先 \(b_i\) 的顺序肯定不会影响匹配,故我们可以直接将 \(b\) 数组从小到大排个序. 我们考虑分析一下什么样的长度为 \(m\) 的数组 \(a_1,a_2,\dots,a_m ...

  6. Codeforces 730L - Expression Queries(大模拟)

    Codeforces 题面传送门 & 洛谷题面传送门 大模拟(?)+阿巴细节题,模拟赛时刚了 3h 最后因为某个细节写挂 100->40/ll/ll(下次一定不能再挂分了啊 awa) 首 ...

  7. 监听浏览器tab切换

    监听浏览器切屏 为了完成验证用户在切换浏览器tab时进行登录再次认证需求需要监听浏览器切换窗口 if (document.hidden !== undefined) { document.addEve ...

  8. 【R】如何将重复行转化为多列(一对一转化一对多)?

    目录 需求 方法一 方法二 需求 一个数据框一列或多列中有重复行,如何将它的重复行转化为多列?即本来两列一对一的关系,如何转化为一对多的关系?普通的spread函数实现较为麻烦. 示例数据如下: It ...

  9. 【机器学*与R语言】2-懒惰学*K*邻(kNN)

    目录 1.理解使用KNN进行分类 KNN特点 KNN步骤 1)计算距离 2)选择合适的K 3)数据准备 2.用KNN诊断乳腺癌 1)收集数据 2)探索和准备数据 3)训练模型 4)评估模型的性能 5) ...

  10. Linux之vi和vim编辑器

    目录 1. vi和vim简介 2. vi 和 vim 的三种常见模式 2.1 正常模式 2.2 插入模式 2.3 命令行模式 3. 三种模式间的切换 4. 常用快捷键案例 5. 常用命令 1. vi和 ...