描述符(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
{}

从上述两个例子中可以看到,类Bvalue属性是一个描述符,当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将类固定为方法的第一个参数。

总结

  1. 描述符是实现了__get____set____del__等特殊方法的类,在属性访问时起着很大的作用。
  2. 数据描述符会覆盖同名的实例属性,通过使用数据描述符,达到通过实例修改类变量的目的。
  3. 描述符用于修改属性的默认访问方式,借此可以实现类方法静态方法

python tips:描述符descriptor的更多相关文章

  1. 【python】描述符descriptor

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

  2. python理解描述符(descriptor)

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

  3. Python 描述符(descriptor) 杂记

    转自:https://blog.tonyseek.com/post/notes-about-python-descriptor/ Python 引入的“描述符”(descriptor)语法特性真的很黄 ...

  4. python描述符descriptor(一)

    Python 描述符是一种创建托管属性的方法.每当一个属性被查询时,一个动作就会发生.这个动作默认是get,set或者delete.不过,有时候某个应用可能会有 更多的需求,需要你设计一些更复杂的动作 ...

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

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

  6. python数据描述符

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

  7. python描述符 descriptor

    descriptor 在python中,如果一个新式类定义了__get__, __set__, __delete__方法中的一个或者多个,那么称之为descriptor.descriptor通常用来改 ...

  8. Python 描述符(Descriptor) 附实例

    在 Python 众多原生特性中,描述符可能是最少被自定义的特性之一,但它在底层实现的方法和属性却无时不刻被使用着,它优雅的实现方式体现出 Python 简洁之美. 定义 一个描述符是一个有" ...

  9. Python 描述符 (descriptor)

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

随机推荐

  1. IOS - 设置与帮助界面

    设置与帮助 改动头像, 改动password, 移动客服, 帮助, 声明, 关于我们. 代码 // // IndexSetting600ViewController.h // SymptomCheck ...

  2. 改善java程序的151个建议--数组和集合

    60.性能考虑,数组是首选,在基本类型处理方面.数组还是占优势的,并且集合类的底层也都是通过数组实现.建议在性能要求较高的场景中使用数组替代集合. 61.假设有必要.使用变长数组:我们能够通过对数组扩 ...

  3. 全然卸载oracle11g步骤

    iLife's 博客http://blog.csdn.net/fei1502816 全然卸载oracle11g步骤: 1. 開始->设置->控制面板->管理工具->服务 停止全 ...

  4. Localhost 回环IP 127.0.0.1

    LocalHost 127.0.0.1是一个保留地址,用于本地软件測试以及本地进程间通信, 也叫回环IP.回环地址.回送地址(loopback address).不管什么程序,一旦使 用回环IP发送数 ...

  5. 【OpenGL】Shader实例分析(九)- AngryBots中的主角受伤特效

    转发请保持地址:http://blog.csdn.net/stalendp/article/details/40859441 AngryBots是Unity官方的一个非常棒的样例.非常有研究价值. 曾 ...

  6. jeasyui-datagrid使用笔记

    formatter转换ID为值 设置字典缓存 var DictionaryItem = {}; $.post('/Dictionary/GetDictionary/T_RKXD', function ...

  7. 插入排序(1)——直接插入排序(insert sort)

    假设有一组无序序列 R0, R1, ... , RN-1. (1) 我们先将这个序列中下标为 0 的元素视为元素个数为 1 的有序序列. (2) 然后,我们要依次把 R1, R2, ... , RN- ...

  8. 51Nod 1250 排列与交换 —— DP

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1250 看了半天... 把第一问想成逆序对的话似乎很容易想了,新加入 ...

  9. E20170623-hm

    verbose  adj. 冗长的,啰唆的,累赘的; reverse   vt. (使) 反转; (使) 颠倒; 掉换,交换; [法] 撤消,推翻;                adj. 反面的; ...

  10. php验证邮箱是否合法

    下面我来总结了在php邮箱验证的正则表达式以及还可以checkdnsrr函数来验证你输入的邮箱是否是有效的哦,这样可以更好的过滤到无效邮箱地址哦.     域名由各国文字的特定字符集.英文字母.数字及 ...