Python描述符以及Property方法的实现原理

描述符的定义:

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

__get__():调用一个属性时,触发

__set__():为一个属性赋值时,触发

__delete__():采用del删除属性时,触发

描述符作用:

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

可以说成是属性的属性,定义属性的属性

描述符本身的实例并不会触发这三个方法

class dis:
def __set__(self, instance, value):
print('正在执行__set__方法.....') def __delete__(self, instance):
print('正在执行__delete__方法') def __get__(self, instance, owner):
print('正在执行__get__方法') d = dis()
d.name = "1"
print(d.name)
del d.name #================输出===================
1

描述符解析

分析代码

class dis:
def __init__(self, fget, fset, fdel):
self.fget = fget
self.fset = fset
self.fdel = fdel
print('正在执行__init__方法.....') def __set__(self, instance, value):
print('正在执行__set__方法.....')
print(instance, value) def __delete__(self, instance):
print('正在执行__delete__方法')
print(instance) def __get__(self, instance, owner):
print('正在执行__get__方法')
print(instance, owner) class test:
def __init__(self, value = 10):
self.value = value
def fset(self, value):
self.value = value
def fget(self):
return self.value
def fdel(self):
del self.value x = dis(fget, fset, fdel) t = test()
print(t.x)
t.x = 20
print(t.x)
del t.x

输出

正在执行__init__方法.....
正在执行__get__方法
<__main__.test object at 0x0000016CA299CEE0> <class '__main__.test'>
None
正在执行__set__方法.....
<__main__.test object at 0x0000016CA299CEE0> 20
正在执行__get__方法
<__main__.test object at 0x0000016CA299CEE0> <class '__main__.test'>
None
正在执行__delete__方法
<__main__.test object at 0x0000016CA299CEE0>

当test类试图去通过x属性来访问自身的value属性时,就会自动跳转到执行dis类里面的__get__方法。

当试图通过x去修改value的属性时就会执行dis类里面的__set__方法。

当试图通过x去删除value的属性时会执行dis类里面的__del__方法。

然后我把它们的参数类型打印出来可以知道;

instance参数指的是test类的实例化对象t;

owner指的是test类;

因为这几个方法我只是把值给打印出来,并未给出有效操作的代码,就返回值一直是None知道了上面之后我们可以实现property方法。

class dis:
def __init__(self, fget = None, fset = None, fdel = None):
self.fget = fget
self.fset = fset
self.fdel = fdel def __set__(self, instance, value):
self.fset(instance, value)#这里fset的参数类型看test里面的fset就行,鸭子类型 def __delete__(self, instance):
self.fdel(instance) def __get__(self, instance, owner):
return self.fget(instance)

以上大概就是property方法,然后再加上测试的代码

class test:
def __init__(self, value = 10):
self.value = value
def fset(self, value):
self.value = value
def fget(self):
return self.value
def fdel(self):
del self.value x = dis(fget, fset, fdel) t = test()
print(t.x)
t.x = 20
print(t.x)
del t.x
try:
print(t.x)
except AttributeError as reason:
print("出错啦"+str(reason))

这里是输出结果:

10
20
出错啦'test' object has no attribute 'value'

Python描述符以及Property方法的实现原理的更多相关文章

  1. Python描述符:property()函数的小秘密

    描述符:将某种特殊类型的类的实例指派给另一个类的属性(注意:这里是类属性,而不是对象属性).而这种特殊类型的类就是实现了__get__,__set__,__delete__这三个方法中的一个或多个的新 ...

  2. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

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

  3. 课时46:魔法方法:描述符(property的原理)

    目录: 一.描述符(property的原理) 二.课时46课后习题及答案 ********************************** 一.描述符(property的原理) ********* ...

  4. 【转载】Python 描述符简介

    来源:Alex Starostin 链接:www.ibm.com/developerworks/cn/opensource/os-pythondescriptors/ 关于Python@修饰符的文章可 ...

  5. Python描述符的使用

    Python描述符的使用 前言 作为一位python的使用者,你可能使用python有一段时间了,但是对于python中的描述符却未必使用过,接下来是对描述符使用的介绍 场景介绍 为了引入描述符的使用 ...

  6. python描述符学习

    目录 一.对象属性的访问控制 二.描述符基本理解 三.基本使用 四.使用描述符完成property.classmethod.staticmethod自定义实现 1.property的自定义实现 2.c ...

  7. Python 描述符 (descriptor)

    1.什么是描述符? 描述符是Python新式类的关键点之一,它为对象属性提供强大的API,你可以认为描述符是表示对象属性的一个代理.当需要属性时,可根据你遇到的情况,通过描述符进行访问他(摘自Pyth ...

  8. 杂项之python描述符协议

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

  9. python描述符理解

    Python中的描述符是一个相对底层的概念 descriptor Any object which defines the methods get(), set(), or delete(). Whe ...

随机推荐

  1. k8s 关于Job与Cronjob

    在Kubernetes 中通过创建工作负载资源 Job 可完成大型计算以及一些批处理任务.比如 Job 转码文件.获取部分文件和目录,机器学习中的训练任务等.这篇小作文我们一起来了解 k8s 中关于 ...

  2. 【c++ Prime 学习笔记】第3章 字符串、向量和数组

    string和vector是两类最重要的标准库类型 strng表示可变长的字符序列 vector存放某种给定类型对象的可变长序列. 3.1 命名空间的using声明 using namespace:: ...

  3. Github 29K Star的开源对象存储方案——Minio入门宝典

    对象存储不是什么新技术了,但是从来都没有被替代掉.为什么?在这个大数据发展迅速地时代,数据已经不单单是简单的文本数据了,每天有大量的图片,视频数据产生,在短视频火爆的今天,这个数量还在增加.有数据表明 ...

  4. [技术博客]大闸蟹的技术博客,通过gitlab api进行用户批量创建

    技术博客--通过gitlab api批量注册用户 gitlab登录界面本身提供了register功能,但需要手工一个个添加,对于一次性会添加整个班级的学生的软工平台来说并不科学合理.使用gitlab ...

  5. Noip模拟68 2021.10.4

    T1 玩水 成功在考试的时候注释掉正解,换成了暴力,只因为不敢保证正解思路的正确 脑子瓦特了,不知道把暴力打成函数拼在一起,不知道当时咋想的.... 就是你找有没有一个点上面和左面的字符一样, 如果这 ...

  6. 集合先从ArrayList开始

    本篇文章非常建议直接从经典Demo开始哦~ 一.ArrayList简介 ArrayList 的底层是数组队列,相当于动态数组.与 Java 中的数组相比,它的容量能动态增长.在添加大量元素前,应用程序 ...

  7. readelf

    readelf的help内容如下所示: Usage: readelf <option(s)> elf-file(s) Display information about the conte ...

  8. 转:Vivado IP报[Opt 31-67] 错误问题解决方法

    使用VIVADO编译代码时,其中一个IP报错,错误类似为 ImplementationOpt Design[Opt 31-67] Problem: A LUT2 cell in the design ...

  9. Python ValueError: Attempted relative import in non-package Relative import相对引用 错误

    包含相对路径import的python脚本不能直接运行,只能作为module被引用. 例如 from . import mod1 有这样代码的文件只能最为moulule为不能直接运行.相对路径就是相对 ...

  10. Luogu P2827 [NOIp2016提高组]蚯蚓 | 神奇的队列

    题目链接 80分思路: 弄一个优先队列,不停地模拟,切蚯蚓时就将最长的那一条出队,然后一分为二入队,简单模拟即可.还要弄一个标记,表示从开始到当前时间每一条蚯蚓应该加上的长度,操作时就加上,入队时就减 ...