轻松理解Python 中的 descriptor

 更新时间:2017年09月15日 09:31:32   投稿:mrr  
本文给大家分Python 中的 descriptor相关知识,非常不错,具有参考借鉴价值,需要的朋友参考下吧

定义

通常,一个 descriptor 是具有“绑定行为”的对象属性。所绑定行为可通过 descriptor 协议被自定义的 __get__() , __set__() 和 __delete__() 方法重写。如果一个对象的上述三个方法任意一个被重写,则就可被称为 descriptor。

属性的默认操作是从对象字典中获取、设置和删除一个属性。例如,a.x 有一个查找链,先 a.__dict__['x'] ,若没有则 type(a).__dict__['x'] ,若没有增往上查找父类直到元类。如果查找链中,对象被定义了 descriptor 方法,Python 就会覆盖默认行为。

Descriptor 是一个强大的工具,虽然开发者不常接触到它,但它其实就是类、属性、函数、方法、静态方法、类方法以及 super() 背后的运行机制。

Descriptor 协议

三个方法原型如下所示:

descr.__get__(self, obj, type=None) --> value
descr.__set__(self, obj, value) --> None
descr.__delete__(self, obj) --> None

数据 descriptor 是同时具有 __get__() 和 __set__() 方法的对象,若只有 __get__() 方法,则为非数据 descriptor。如果实例字典中有和数据 descriptor 同名的入口,则数据 descriptor 优先级更高。相反,非数据 descriptor 优先级低。

让 __set__() 方法抛出异常,就能创建一个只读数据 descriptor。

调用 descriptor

descriptor 可以直接通过方法名调用。例如, d.__get__(obj) 。

而通过访问对象属性,自动调用 descriptor 才是更通用的做法。例如,如果 d 定义了方法 __get__() ,则 obj.d 会调用 d.__get__(obj) 。

对于对象, b.x 会被转换成 type(b).__dict__['x'].__get__(b, type(b)) 。而对于类(是的,类也可以调用), B.x 会被转换成 B.__dict__['x'].__get__(None, B) 。

Descriptor 例子

class RevealAccess(object):
  """A data descriptor that sets and returns values
    normally and prints a message logging their access.
  """
  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(object):
...   x = RevealAccess(10, 'var "x"')
...   y = 5
...
>>> m = MyClass()
>>> m.x
Retrieving var "x"
10
>>> m.x = 20
Updating var "x"
>>> m.x
Retrieving var "x"
20
>>> m.y
5

总结

以上所述是小编给大家介绍的Python 中的 descriptor,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • python三元运算符实现方法

    python三元运算符实现方法

    这篇文章主要介绍了python实现三元运算符的方法,大家参考使用吧
    2013-12-12
  • Python函数式编程实例详解

    Python函数式编程实例详解

    这篇文章主要介绍了Python函数式编程,结合实例形式详细分析了Python函数式编程高阶函数、匿名函数、闭包及函数装饰器等相关概念、原理与使用技巧,需要的朋友可以参考下
    2020-01-01
  • python对DICOM图像的读取方法详解

    python对DICOM图像的读取方法详解

    DICOM(Digital Imaging and Communications in Medicine)即医学数字成像和通信,是医学图像和相关信息的国际标准(ISO 12052)。下面这篇文章主要给大家介绍了关于python对DICOM图像读取的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-07-07
  • 一文深入学习Python中的os.listdir函数

    一文深入学习Python中的os.listdir函数

    这篇文章主要给大家介绍了关于Python中os.listdir函数的相关资料,os.listdir是 Python中的一个函数,它的意思是返回指定目录下的文件和文件夹的名称的列表,需要的朋友可以参考下
    2023-10-10
  • Python真题案例之小学算术 阶乘精确值 孪生素数 6174问题详解

    Python真题案例之小学算术 阶乘精确值 孪生素数 6174问题详解

    这篇文章主要介绍了python实操案例练习,本文给大家分享的案例中主要任务有小学生算术、阶乘的精确值、孪生素数、6174问题,需要的小伙伴可以参考一下
    2022-03-03
  • python 在sql语句中使用%s,%d,%f说明

    python 在sql语句中使用%s,%d,%f说明

    这篇文章主要介绍了python 在sql语句中使用%s,%d,%f说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • NumPy实现从已有的数组创建数组

    NumPy实现从已有的数组创建数组

    本文介绍了NumPy中如何从已有的数组创建数组,包括使用numpy.asarray,numpy.frombuffer和numpy.fromiter方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-10-10
  • Python自动安装第三方库的小技巧(pip使用详解)

    Python自动安装第三方库的小技巧(pip使用详解)

    很多朋友私信小编Python安装第三方库安装技巧,在这就不一一回复大家了,今天小编给大家分享一篇教程关于Python自动安装第三方库的小技巧,本文以安装plotly为例给大家详细讲解,感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • Python3实现转换Image图片格式

    Python3实现转换Image图片格式

    本篇文章给大家分享了Python3实现在线转换Image图片格式的功能以及相关实例代码,有兴趣的朋友参考下。
    2018-06-06
  • django下创建多个app并设置urls方法

    django下创建多个app并设置urls方法

    在本篇文章里小编给大家分享的是一篇关于django下创建多个app并设置urls方法,需要的朋友们可以参考学习下。
    2020-08-08

最新评论