Python 描述符简述

2023-11-11

Python 中,通过使用描述符,可以让程序员在引用一个对象属性时自定义要完成的工作。

本质上看,描述符就是一个类,只不过它定义了另一个类中属性的访问方式。换句话说,一个类可以将属性管理全权委托给描述符类。

描述符是 Python 中复杂属性访问的基础,它在内部被用于实现 property、方法、类方法、静态方法和 super 类型。

描述符类基于以下 3 个特殊方法,换句话说,这 3 个方法组成了描述符协议:

  1. __set__(self, obj, type=None):在设置属性时将调用这一方法(本节后续用 setter 表示);
  2. __get__(self, obj, value):在读取属性时将调用这一方法(本节后续用 getter 表示);
  3. __delete__(self, obj):对属性调用 del 时将调用这一方法。

其中,实现了 setter 和 getter 方法的描述符类被称为数据描述符;反之,如果只实现了 getter 方法,则称为非数据描述符。

实际上,在每次查找属性时,描述符协议中的方法都由类对象的特殊方法 __getattribute__() 调用(注意不要和 __getattr__() 弄混)。也就是说,每次使用类对象.属性(或者 getattr(类对象,属性值))的调用方式时,都会隐式地调用 __getattribute__(),它会按照下列顺序查找该属性:

  1. 验证该属性是否为类实例对象的数据描述符;
  2. 如果不是,就查看该属性是否能在类实例对象的 __dict__ 中找到;
  3. 最后,查看该属性是否为类实例对象的非数据描述符。

为了表达清楚,这里举个例子:

#描述符类
class revealAccess:
    def __init__(self, initval = None, name = 'var'):
        self.val = initval
        self.name = name
    def __get__(self, obj, objtype):
        print("Retrieving",self.name)
        return self.val
    def __set__(self, obj, val):
        print("updating",self.name)
        self.val = val
class myClass:
    x = revealAccess(10,'var "x"')
    y = 5
m = myClass()
print(m.x)
m.x = 20
print(m.x)
print(m.y)

运行结果为:

Retrieving var "x"
10
updating var "x"
Retrieving var "x"
20
5

从这个例子可以看到,如果一个类的某个属性有数据描述符,那么每次查找这个属性时,都会调用描述符的 __get__() 方法,并返回它的值;同样,每次在对该属性赋值时,也会调用 __set__() 方法。

注意,虽然上面例子中没有使用 __del__() 方法,但也很容易理解,当每次使用 del 类对象.属性(或者 delattr(类对象,属性))语句时,都会调用该方法。

除了使用描述符类自定义类属性被调用时做的操作外,还可以使用 property() 函数或者 @property 装饰器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 描述符简述 的相关文章

随机推荐

  • 大数据实习生的面试总结

    不同的公司面试内容不同 有的注重基础知识有的注重项目 对实习生 也就是应届生 更多的是基础 因为没有什么工作经验 项目很多也不怎么样 所以也就问的少 下面是我的一点面试经验 我面试次数不多 可能是运气比较好 几家就有了一个很满意的 一共面过
  • 说一下从Java API层面上的6种线程状态

    新建 New 这是属于一个已经创建的线程 但是还没有调用start方法启动的线程所处的状态 可运行 Runnable 该状态包含两种可能 有可能正在运行 或者正在等待CPU资源 包含了操作系统线程状态种的运行 可运行状态和阻塞状态 由于 B
  • burp如何设置微信小程序代理

    一 简介 没有废话 测试app 小程序 不知道怎么弄代理就看这个 算了 毕竟是自己的博客 还是先吐槽几句 我是小白一个 不知道怎么测app 最凄凉的连怎么代理都不知道 mmp 那老子百度把 行 第一次 夜神模拟器 搞一搞 看了不错的文章 写
  • WF攻击(网站指纹攻击)

    网站指纹 WF 攻击是被动的本地攻击者通过比较用户发送和接收的数据包序列与先前记录的数据集来确定加密互联网流量的目的地 可以通过网络流量中的模式来识别Tor用户访问过的页面 因此 WF攻击是Tor等隐私增强技术特别关注的题 攻击过程 该攻击
  • ant design vue表格拖拽排序sortTableJS

    最近用sortTableJS做了个基于antd的拖拽排序功能 话不多说直接上效果 列表拖拽 可以去官网细读文档sortTableJS 一 npm或yarn引入sortablejs包 npm install sortablejs yarn a
  • 中文出现乱码最常见的几种方式解析

    1 出现古文夹杂日韩文 以GBK读取UTF 8编码 2 出现方块形 以UTF 8读取GBK 3 各种符号 以ISO8859 1方式读取UTF 8 4 拼音码 带声调的字母 以ISO8859 1方式读取GBK 5 长度为奇数时 最后的字符变成
  • docker学习:镜像以及镜像命令

    docker镜像 docker在安装好就要涉及到镜像的部分 首先要知道镜像是啥以及它的作用 docker可以理解是一个模板 这个模板我们可以通过它启动一个或者多个容器 镜像本身是一个精简的操作系统 里面有设置好的环境和依赖 像一个停止的容器
  • Error opening framebuffer device /dev/fb0

    export QT QWS DISPLAY linuxFB dev fb0 哎呀搞错了 解决方法在这边 另外一个类似的 链接到这边解决 1 Error opening framebuffer device dev fb0 关于这个错误 除了
  • Linux进程间通信--ftok

    在C语言中 ftok函数用于生成一个唯一的键值 该键值通常用于创建共享内存 消息队列和信号量等系统资源的标识符 ftok函数原型入下 key t ftok const char pathname int proj id 参数说明 pathn
  • javascript 大数值数据运算

    javascript数字运算结果不准确 1 浮点型数字进行运算时 基本四则运算结果都可能不准确 一般是把浮点型数据转换为整型运算 然后在还原处理 这种情况下可以用一些常用转换方法计算 如下 1 2 加法运算 3 4 function num
  • tomcat 日志级别修改

    在 TOMCAT HOME conf 目录下有个loggin properties文件 Handler specific properties Describes specific configuration info for Handle
  • python进入虚拟环境 找不到module_centos安装Python插件后找不到对应的插件ModuleNotFoundError: No module named*...

    题记 在之前的文章中 我在centos服务器装了python3并且给python与pip建立了软链 利用git上传代码到centos服务器之后利用终端运行app py的时候会报错 报错 root izm5e0qcppq4b6rgy4d5vf
  • 如何利用Python自动发邮件

    在工作中 每天或者每周结束的时候我们都会发送相应的日报或者周报给上级领导 来汇报你做了那些工作 可是汇报工作内容的时候我们始终都是打开邮箱 写入内容 发送和抄送给固定的人 那么这么繁琐并且重复的一件事 我们能不能使用程序来简化 答案是可以的
  • SqlServer数据库中文乱码

    可以在建立数据时指定排序规则 记得选中文简体 Chinese PRC CS AI WS 如果数据库中已经有数据 则转换 编码会失败
  • Android Studio编译异常Error: Program type already present: android.support.design.widget.CoordinatorLayo

    记录一下 希望能帮到小伙伴 解决的方案在build gradle修改 implementation com android support design 25 1 0 修改为 implementation com android suppo
  • Centos6 升级glibc-2.17,解决Requires: libc.so.6(GLIBC_2.17)(64bit)错误解决方法

    在Centos6安装mysql 8 0 33系列提示错误如下 root rhel64 Downloads rpm ivh mysql community common 8 0 33 1 el6 x86 64 rpm gt mysql com
  • frp内网穿透实验

    Frp Fast Reverse Proxy 是比较流行的一款 FRP 是一个免费开源的用于内网穿透的反向代理应用 它支持 TCP UDP 协议 也为 http 和 https 协议提供了额外的支持 你可以粗略理解它是一个中转站 帮你实现
  • 如何用Java对Excel表进行读写操作?

    博主公众号 没有腹肌的程序猿 公众号会不定期更新一些数据集 有需要的可以点点关注哦 如何用Java对Excel表进行读写操作 1 Java读取Excel表的内容 Java读取Excel表相对来说还是比较简单的 分为3步 首先是先读取文件 再
  • 浮动的特点

    一 什么是浮动 1 浮动概念 是一种布局方式 可以让元素脱离文档流 一旦元素脱离文档流 就不再具有元素在文档流中的特点 从而帮助我们布局 2 设置浮动 float样式名 可选值 none 不浮动 默认值 left 向左浮动 right 向右
  • Python 描述符简述

    Python 中 通过使用描述符 可以让程序员在引用一个对象属性时自定义要完成的工作 本质上看 描述符就是一个类 只不过它定义了另一个类中属性的访问方式 换句话说 一个类可以将属性管理全权委托给描述符类 描述符是 Python 中复杂属性访