一文掌握 Python 的描述符协议
描述符介绍
描述符本质就是一个新式类,在这个新式类中,至少要实现了__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:要严格遵循该优先级,优先级由高到底分别是
- 类属性
- 数据描述符
- 实例属性
- 非数据描述符
- 找不到的属性触发
__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 的描述符协议的更多相关文章
- 杂项之python描述符协议
杂项之python描述符协议 本节内容 由来 描述符协议概念 类的静态方法及类方法实现原理 类作为装饰器使用 1. 由来 闲来无事去看了看django中的内置分页方法,发现里面用到了类作为装饰器来使用 ...
- Iterator Protocol - Python 描述符协议
Iterator Protocol - Python 描述符协议 先看几个有关概念, iterator 迭代器, 一个实现了无参数的 __next__ 方法, 并返回 '序列'中下一个元素,在没有更多 ...
- Descriptor - Python 描述符协议
描述符(descriptor) descriptor 是一个实现了 __get__. __set__ 和 __delete__ 特殊方法中的一个或多个的. 与 descriptor 有关的几个名词解释 ...
- python理解描述符(descriptor)
Descriptor基础 python中的描述符可以用来定义触发自动执行的代码,它像是一个对象属性操作(访问.赋值.删除)的代理类一样.前面介绍过的property是描述符的一种. 大致流程是这样的: ...
- Python属性描述符(一)
描述符是对多个属性运用相同存取逻辑的一种方式,,是实现了特性协议的类,这个协议包括了__get__.__set__和__delete__方法.property类实现了完整的描述符协议.通常,可以只实现 ...
- python数据描述符
Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题苦恼的朋友提 ...
- 【python】描述符descriptor
开始看官方文档,各种看不懂,只看到一句Properties, bound and unbound methods, static methods, and class methods are all ...
- python Descriptor (描述符)
简介: python 描述符是新式类(继承自object)中的语言协议,基于描述符可以提供更佳优雅的解决方案. python的classmethod, staticmethod, property都是 ...
- python - 数据描述符(class 内置 get/set/delete方法 )
数据描述符(class 内置 get/set/del方法 ): # 什么是描述符 # 官方的定义:描述符是一种具有“捆绑行为”的对象属性.访问(获取.设置和删除)它的属性时,实际是调用特殊的方法(_g ...
随机推荐
- Hadoop集群 增加节点/增加磁盘
在虚拟机中新建一个机器. 设置静态IP 将修改/etc/hosts 192.168.102.10 master 192.168.102.11 slave-1 192.168.102.12 slave- ...
- MySQL语法练习一
DESC t_dept ALTER TABLE t_dept ADD descri VARCHAR(20) ALTER TABLE t_dept ADD decribe VARCHAR(20) FIR ...
- [hdu7013]String Mod
枚举$a$和$b$出现的次数,问题即求$$A_{i,j}=\sum_{p=0}^{L}\sum_{q=0}^{L-p}[n\mid (p-i)][n\mid (q-j)]{L\choo ...
- [GYCTF2020]Easyphp
知识点 反序列化pop链 反序列化字符逃逸 解题过程 www.zip 备份文件获取源码 审计代码构造pop链 <?php Class UpdateHelper{ public $id; publ ...
- 『与善仁』Appium基础 — 14、Appium测试环境搭建
目录 1.Appium测试环境搭建整体思路 (1)Android测试环境搭建 (2)Appium测试环境搭建 (3)测试脚本语言的环境搭建 2.Appium在Android端和IOS端的工作流程 (1 ...
- 【备考06组01号】第四届蓝桥杯JAVA组A组国赛题解
1.填算式 (1)题目描述 请看下面的算式: (ABCD - EFGH) * XY = 900 每个字母代表一个0~9的数字,不同字母代表不同数字,首位不能为0. 比如 ...
- Codeforces 453E - Little Pony and Lord Tirek(二维线段树+ODT)
Codeforces 题目传送门 & 洛谷题目传送门 一道难度 *3100 的 DS,而且被我自己搞出来了! 不过我终究还是技不如人,因为这是一个 \(n\log^2n\) + 大常数的辣鸡做 ...
- 【3】蛋白鉴定软件之Mascot
目录 1.简介 2.配置 2.1在线版本 2.2 服务器版本 3.运行 3.1 在线版本 3.2 服务器版本 4.结果 1.简介 Mascot是非常经典的蛋白鉴定软件,被Frost & Sul ...
- 【R方差分析】蛋白质表达量多组比较
初始数据类似: 蛋白质组数据虽不是严格的正态分布,但目前最常用的检验方法还是T检验(两组比较)和方差分析(多组比较).这个话题值得深究,这里不展开. 主要是求多个蛋白的Pvalue值或FDR,用于差异 ...
- R shinydashboard——3.外观
目录 1.皮肤 2.注销面板 3.CSS 4. 标题延长 5.侧边栏宽度 6.图标 7.状态和颜色 1.皮肤 shinydashboard有很多颜色主题和外观的设置.默认为蓝色,可指定黑丝.紫色.绿色 ...