python:一段代码看懂Descriptor

先看代码和执行结果,很简单:

image.png

然后去掉第18行的注释:


image.png

和之前唯一的区别是第25行的输出。
想一想:为什么第21行定义的self.p没有覆盖第18行定义的类属性p?

因为这里的类属性p是Descriptor(这里为class P)的实例
来看看完整的代码:

#!/usr/bin/env python3                  
                                        
class P:                                
    def __init__(self, v):              
        self.data = v                   
                                        
    def __get__(self, ins, cls):        
        return self.data                
                                        
    def __set__(self, ins, v):          
        self.data = v                   
                                        
    def __delete__(self, ins):          
        del self.data                   
                                        
                                        
class A:                                
    p = P(1)                            
                                        
    def __init__(self, v):              
        self.p = v                      
        self.x = v                      
                                        
obj = A(1)                              
print(obj.__dict__)                     
print(obj.p)                            
                                        
obj.p = 2                               
print(obj.p)                            
                                        
del obj.p                               
print(hasattr(obj, 'p'))                
                                        
obj.p = 3                               
print(hasattr(obj, 'p'))                

类属性p相当于代理了对class A中成员p的所有访问、修改、删除操作
p的值实际存储于class P的self.data

要想正确使用Descriptor必须满足这几点:
其中第一点只是用来还原测试代码的输出,实际可以不定义self.p

image.png

Descriptor几个方法的相关参数介绍:

  • 参数ins:为第24行定义的obj
  • 参数cls:为class A
  • 参数v : 将要给p赋的值

扩展:

  1. 类中定义的类函数和方法都是Descriptor
  2. 数据描述符(实现了__set__函数)会覆盖同名实例属性(self.p)
  3. 描述符是通过__getattribute__()方法经由__dict__访问的,所以数据描述符要放在类属性中
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,827评论 0 9
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,242评论 6 13
  • 要点: 函数式编程:注意不是“函数编程”,多了一个“式” 模块:如何使用模块 面向对象编程:面向对象的概念、属性、...
    victorsungo阅读 1,606评论 0 6
  • Python 面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对...
    顺毛阅读 4,257评论 4 16
  • 典故这个名称,最早可追溯到汉朝,《后汉书.东平宪王苍传》:“亲屈至尊,降礼下臣,每赐宴见,辄兴席改容,中宫亲拜,事...
    悠游四海阅读 1,027评论 0 1