Python描述符descriptor使用原理解析
作者:luoheng 发布时间:2022-03-24 20:12:48
描述符(descriptor)是实现了__get__、__set__、__del__方法的类,进一步可以细分为两类:
数据描述符:实现了__get__和__set__
非数据描述符:没有实现__set__
描述符在类的属性调用中起着很重要的作用,类在调用属性时,遵守两个规则:
按照实例属性、类属性的顺序选择属性,即实例属性优先于类属性
如果在类属性中发现同名的数据描述符,那么该描述符会优先于实例属性
非数据描述符会被实例属性覆盖
class A:
def __get__(self, obj, cls):
return f"{obj}: get"
class B:
value = A()
def __init__(self):
self.value = 4
def main():
g = B()
print(g.value)
print(g.__dict__)
if __name__ == "__main__":
main()
输出结果
4
{'value': 4}
数据描述符优于实例属性
class A:
def __get__(self, obj, cls):
return f"{obj}: get"
def __set__(self, obj, value):
print(f"{obj}: set, {value}")
class B:
value = A()
def __init__(self):
self.value = 4
def main():
g = B()
print(g.value)
print(g.__dict__)
if __name__ == "__main__":
main()
输出结果
<__main__.B object at 0x000001165EB85898>: set, 4
<__main__.B object at 0x000001165EB85898>: get
{}
从上述两个例子中可以看到,类B的value属性是一个描述符,当value属性是一个数据描述符时,它屏蔽了实例的同名属性value,实例对value属性的读取与赋值都会直接被转移到类属性value上。
使用描述符实现类的静态方法与类方法
from functools import partial
class Staticmethod:
def __init__(self, method):
self.method = method
def __get__(self, obj, cls):
return self.method
class Classmethod:
def __init__(self, method):
self.method = method
def __get__(self, obj, cls):
return partial(self.method, cls)
class A:
@Staticmethod
def f(self):
print(f"I'm method f, the value is {self}")
@Classmethod
def c(self):
print(f"my class is {self}")
a = A()
a.f(23)
A.f(23)
a.c()
A.c()
输出结果
I'm method f, the value is 23
I'm method f, the value is 23
my class is <class '__main__.A'>
my class is <class '__main__.A'>
静态方法与类方法统一了类属性的两种引用方式。这种统一的过程可以使用描述符修改属性访问的默认方式实现。静态方法限制实例的默认绑定,将方法当做普通函数使用;类方法始终将类作为第一个参数传入,上述的partial将类固定为方法的第一个参数。
总结
描述符是实现了__get__、__set__、__del__等特殊方法的类,在属性访问时起着很大的作用。
数据描述符会覆盖同名的实例属性,通过使用数据描述符,达到通过实例修改类变量的目的。
描述符用于修改属性的默认访问方式,借此可以实现类方法与静态方法。
来源:https://www.cnblogs.com/luoheng23/p/11083398.html


猜你喜欢
- 本文实例讲述了Python3实现获取图片文字里中文的方法。分享给大家供大家参考,具体如下:一、运行环境(1) win10(2) pychar
- 本文实例讲述了JS实现控制表格内指定单元格内容对齐的方法。分享给大家供大家参考。具体如下:下面的代码控制表格单元格的内容向右对齐<!D
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&
- 实例如下所示:tcode={}transcode={}def GetTcode():#从文本中获取英文对应的故障码,并保存在tcode字典(
- 如下所示:#获得视频的格式videoCapture = cv2.VideoCapture('/home/lw/3661.mp4
- 表格内容根据票据日期升序(这里是已经排序后的效果)上代码代码中data的内容如下根据paper_date排序,因为目前这种格式不支持比较,需
- 本文实例讲述了PHP使用PHPexcel导入导出数据的方法。分享给大家供大家参考,具体如下:导入数据:<?phperror_repor
- 本文实例讲述了PHP中使用addslashes函数转义的安全性原理分析。分享给大家供大家参考。具体分析如下:先来看一下ECshop中adds
- 前段时间,接到一个需求,要求下载某一个网站的视频,然后自己从网上查阅了相关的资料,在这里做一个总结。1. m3u8文件m3u8是苹果公司推出
- 参考廖雪峰的Python教程,实现Linux Python3获取雅虎天气#!/usr/bin/env python3# coding: ut
- FlaskFlask是什么?Flask是一个使用 Python 编写的轻量级 Web 应用框架, 让我们可以使用Python语言快速搭建We
- 最近为数据库服务器增加了内存,达到了最大支持的8G,数据库用的是mssql 2005 ,之前内存一直是4G的,不存在内存大和32位操作系统冲
- 本文实例讲述了GO语言标准错误处理机制error用法。分享给大家供大家参考。具体分析如下:在 Golang 中,错误处理机制一般是函数返回时
- OpenCV 对象跟踪这篇文章使用 OpenCV 中内置的八种不同的对象跟踪算法,实现对物体的跟踪。首先,介绍一下8种跟踪算法。然后,演示如
- 最近在Ubuntu16.04上安装Python3.6之后,使用pip命令出现了问题,提示说找不到ssl模块,出现错误如下:pip is co
- 本文实例讲述了JS上传图片前实现图片预览效果的方法。分享给大家供大家参考。具体实现方法如下:<!doctype html public
- 直接将 视频的HTML网址存入models ,以字符串的形式#关于我们 CharFieldclass About(models.Model)
- 事情开始得很简单。MegaWare公司市场部门想要一个新的网站来发布文档,开发团队觉得使用SQL Server 2000数据库作为文档存储仓
- 为何选Nuxt.js?在前后端分离出现之前,传统的web页面都是服务端渲染的,如JSP、PHP、Python Django,还有各种模板技术
- 本文实例讲述了Python实现监控Nginx配置文件的不同并发送邮件报警功能。分享给大家供大家参考,具体如下:因为项目中经常涉及到多个Ngi