• 描述符


    一、概念:

    Python 中,通过使用描述符,可以让程序在引用一个对象属性时自定义要完成的工作。

    本质上看,描述符就是一个类,只不过它定义了另一个类中属性的访问方式。

    换句话说,一个类可以将属性全权委托给描述符类。

    描述符类基于以下3个特殊方法:

    ♦ __set__ (self, instance, value)   设置属性调用

    ♦ __get__(self,instance, owner) 访问属性调用

    ♦ __delete__(self, instance) 对属性调用del 时将调用这一方法

    二、描述符分两种

    ①数据描述符:至少实现了 __get__()和__set__()

    class Foo:
        def __set__(selfsself,instance, value):
            print("set")
        def __get__(self, instance, owner):
            print("get")
            
    

    ②非数据描述符:没有实现__set__()

    class Foo:
    
        def __get__(self, instance, owner):
            print("get")
    

    实例:  

    class Foo:
        def __get__(self, instance, owner):   #这里的instance是实例对象b1,owner是类Bar
            print("===>get方法")
            return instance.__dict__['x']
        def __set__(self, instance, value):  #这里的instance是实例对象b1,value是传入的值
            print("===>set方法")
            instance.__dict__['x'] = value
        def __delete__(self, instance):
            print("===>delete方法")
            instance.__dict__.pop('x')
    
    class Bar:
        x = Foo()   #将x 全权给Foo类代理,此时 x 就是描述符
        def __init__(self, n):
            self.x = n
    
    b1 = Bar(10)
    print(b1.__dict__)
    print(b1.x)
    del b1.x
    print(b1.__dict__)
    b1.x = 222222222
    print(b1.__dict__)
    b1.y = 2222
    print(b1.__dict__)
    

      

    三、描述符优先级

    类属性 > 数据描述符 > 实例属性 > 非数据属性 > 找不到的属性触发__getattr__

    class Foo:
        def __get__(self, instance, owner):   #这里的instance是实例对象b1,owner是类Bar
            print("===>get方法")
            # return instance.__dict__['x']
        def __set__(self, instance, value):  #这里的instance是实例对象b1,value是传入的值
            print("===>set方法")
            # instance.__dict__['x'] = value
        def __delete__(self, instance):
            print("===>delete方法")
            # instance.__dict__.pop('x')
    class Bar:
        x = Foo()
        def __init__(self, n):
            self.x = n
    
    b1 = Bar(10)
    print(Bar.__dict__)  #这里打印字典看出:x 是一个对象
    Bar.x = 10
    print(Bar.x)
    print(Bar.__dict__)  #当Bar.x为x后,直接覆盖了描述符的操作
    

    class Foo:
        def __get__(self, instance, owner):   #这里的instance是实例对象b1,owner是类Bar
            print("===>get方法")
            # return instance.__dict__['x']
        def __set__(self, instance, value):  #这里的instance是实例对象b1,value是传入的值
            print("===>set方法")
            # instance.__dict__['x'] = value
        def __delete__(self, instance):
            print("===>delete方法")
            # instance.__dict__.pop('x')
    class Bar:
        x = Foo()
        def __init__(self, n):
            self.x = n
    
    b1 = Bar(10)
    b1.x = 10  #可以看出。用实例为变量赋值时,直接触发数据描述符
    print(b1.__dict__)
    

      

    class Foo:
        def __get__(self, instance, owner):   #这里的instance是实例对象b1,owner是类Bar
            print("===>get方法")
            # return instance.__dict__['x']
        # def __set__(self, instance, value):  #这里的instance是实例对象b1,value是传入的值
        #     print("===>set方法")
        #     # instance.__dict__['x'] = value
        # def __delete__(self, instance):
            print("===>delete方法")
            # instance.__dict__.pop('x')
    class Bar:
        x = Foo()
        def __init__(self, n):
            self.x = n
    
    b1 = Bar(10)
    b1.x = 10  #可以看出。用实例为变量赋值时,没有触发非数据描述符
    print(b1.__dict__)
    

     

    class Foo:
        def __get__(self, instance, owner):   #这里的instance是实例对象b1,owner是类Bar
            print("===>get方法")
            # return instance.__dict__['x']
        # def __set__(self, instance, value):  #这里的instance是实例对象b1,value是传入的值
        #     print("===>set方法")
        #     # instance.__dict__['x'] = value
        # def __delete__(self, instance):
            print("===>delete方法")
            # instance.__dict__.pop('x')
    class Bar:
        x = Foo()
        def __init__(self, n):
            self.x = n
        def __getattr__(self, item):
            print("qaq")
    
    b1 = Bar(10)
    b1.yyyy   #当查找的属性不存在时
    

      

      

    一个奋斗中的产品小白
  • 相关阅读:
    指向老域名的反链丢失问题
    oracle express介绍
    VB6:通过ADO访问Oracle存储过程返回的结果集
    Oracle学习笔记:理解oracle的编程接口oo4o的对象模型
    Oracle学习笔记:oracle的编程接口
    VB6:编写一个分析sqlserver存储过程执行语句"execute procedurename par1,par2,......."语法是否正确的函数
    惊喜!使用Regcure修复注册表错误,Oracle客户端可以使用了
    最新30佳精美的名片设计作品欣赏
    28个经过重新设计的著名博客案例
    向设计师推荐20款漂亮的免费英文字体
  • 原文地址:https://www.cnblogs.com/dabai123/p/11630584.html
Copyright © 2020-2023  润新知