Python描述符descriptor使用原理解析

 更新时间:2020年03月21日 12:24:05   作者:luoheng  
这篇文章主要介绍了Python 描述符descriptor使用原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

描述符(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__等特殊方法的类,在属性访问时起着很大的作用。
  • 数据描述符会覆盖同名的实例属性,通过使用数据描述符,达到通过实例修改类变量的目的。
  • 描述符用于修改属性的默认访问方式,借此可以实现类方法与静态方法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • python实现跳表SkipList的示例代码

    python实现跳表SkipList的示例代码

    这篇文章主要介绍了python实现跳表SkipList的示例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • 基于PyQt5实现一个串口接数据波形显示工具

    基于PyQt5实现一个串口接数据波形显示工具

    这篇文章主要为大家详细介绍了如何利用PyQt5实现一个串口接数据波形显示工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-01-01
  • Pytorch GPU内存占用很高,但是利用率很低如何解决

    Pytorch GPU内存占用很高,但是利用率很低如何解决

    这篇文章主要介绍了Pytorch GPU内存占用很高,但是利用率很低的原因及解决方法,具有很好的参考价值,希望对大家 有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • python优化测试稳定性的失败重试工具pytest-rerunfailures详解

    python优化测试稳定性的失败重试工具pytest-rerunfailures详解

    笔者在执行自动化测试用例时,会发现有时候用例失败并非代码问题,而是由于服务正在发版,导致请求失败,从而降低了自动化用例的稳定性,那该如何增加失败重试机制呢?带着问题我们一起探索
    2023-10-10
  • Python编辑和运行的四种方式

    Python编辑和运行的四种方式

    本篇内容主要是讲python在电脑上编辑和运行的几种不同方式,后面主要是在pycharm中去写代码,然后运行,其实还有其他的方式可以在电脑上写python代码和运行python代码,需要的朋友可以参考下
    2024-08-08
  • Python数据可视化之画图

    Python数据可视化之画图

    今天小编就为大家分享一篇关于Python数据可视化之画图,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • python gravis库实现图形数据可视化实例探索

    python gravis库实现图形数据可视化实例探索

    这篇文章主要为大家介绍了python gravis库实现图形数据可视化实例探索,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-02-02
  • OpenAI Function Calling特性示例详解

    OpenAI Function Calling特性示例详解

    这篇文章主要为大家介绍了OpenAI Function Calling特性作用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 提高python代码运行效率的一些建议

    提高python代码运行效率的一些建议

    这篇文章主要介绍了提高python代码运行效率的一些建议,帮助大家优化python代码,提高运行效率,感兴趣的朋友可以了解下
    2020-09-09
  • python随机生成大小写字母数字混合密码(仅20行代码)

    python随机生成大小写字母数字混合密码(仅20行代码)

    这篇文章主要介绍了python随机生成大小写字母数字混合密码,主要是利用random模块随机生成数字,大小写字母,通过循环次数来实现此功能,需要的朋友可以参考下
    2020-02-02

最新评论