python tips:描述符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
{}

从上述两个例子中可以看到,类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. 描述符用于修改属性的默认访问方式,借此可以实现类方法静态方法

原文地址:https://www.cnblogs.com/luoheng23/p/11083398.html

时间: 2024-10-28 20:14:16

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

python描述符descriptor(二)

python内置的描述符 python有些内置的描述符对象,property.staticmethod.classmethod,python实现如下: class Property(object): def __init__(self,getf,setf,delf,doc): self.getf=getf self.setf=setf self.delf=delf self.doc=doc def __set__(self,instance,own=None): if instance is N

Python 描述符(descriptor) 杂记

转自:https://blog.tonyseek.com/post/notes-about-python-descriptor/ Python 引入的“描述符”(descriptor)语法特性真的很黄很暴力,我觉得这算是 Python 对象模型的核心成员之一.Python 语言设计的紧凑很大程度上得益于它.所以写一篇笔记文记录关于描述符我知道的一切. 低层 - 纯纯的描述符 纯纯的描述符很纯,基于类中定义的 __get__ . __set__ . __delete__ 三个特殊的方法.实现了这三

python描述符descriptor(一)

Python 描述符是一种创建托管属性的方法.每当一个属性被查询时,一个动作就会发生.这个动作默认是get,set或者delete.不过,有时候某个应用可能会有 更多的需求,需要你设计一些更复杂的动作.最好的解决方案就是编写一个执行符合需求的动作的函数,然后指定它在属性被访问时运行.一个具有这种功能的对象 称为描述符.描述符是python方法,绑定方法,super,property,staticmethod和classmethod的实现基础. 1.描述符协议 描述符descriptor就是一个表

Python属性描述符(二)

Python存取属性的方式特别不对等,通过实例读取属性时,通常返回的是实例中定义的属性,但如果实例未曾定义过该属性,就会获取类属性,而为实例的属性赋值时,通常会在实例中创建属性,而不会影响到类本身.这种不对等的方式对描述符类也有影响. def cls_name(obj_or_cls): # 传入一个实例,返回类名 cls = type(obj_or_cls) if cls is type: cls = obj_or_cls return cls.__name__.split('.')[-1] d

python之描述符

描述符是将某种特殊类型的类实例指派给另一个类的属性,某种特殊类型的类就是这个类里面封装了get,set,delete这三个方法,可以将这个类指派给另一个类的某一个属性,这样就可以通过这三个方法对该属性进行操作,举例如下 1 class MyDecriptor: 2 def __set__(self,instance,value): 3 print('set') 4 def __get__(self,instance,owner): 5 print('get') 6 def __delete__(

Python属性描述符(一)

描述符是对多个属性运用相同存取逻辑的一种方式,,是实现了特性协议的类,这个协议包括了__get__.__set__和__delete__方法.property类实现了完整的描述符协议.通常,可以只实现部分协议,如只实现了__get__或__set__,而不必把__get__.__set__和__delete__全部实现 现在,让我们用描述符协议升级上一个章节Python动态属性和特性(二)的LineItem类 图1-1 我们将定义一个Quantity类,LineItem类会用到两个Quantit

python 属性描述符及属性查找顺序

1 import numbers 2 class IntField: # 当一个类实现了 __get__, __set__, __delete__ 3 """ 4 数据描述符 5 """ 6 def __get__(self, instance, owner): 7 return self.value 8 def __set__(self, instance, value): 9 if not isinstance(value, numbers.

[TimLinux] Python 自定义描述符

1. 含义 在类中,含有属性(该属性需要存在类对象到__dict__属性中,不能为存在示例对象的__dict__属性中),对属性对操作(访问,设置值,删除)可以自定义行为,这样对自定义行为成为自定义属性描述符(Descriptor),这样的属性对象来自相应对类,这样的类称为描述符类. 2. 结构 class A(object): pass # 实现任一一个或多个:__get__, __set__, __delete__, __set_name__ # 类A称为描述符类 class T(objec

Python进阶-----描述符(__get__(),__set__(),__delete__())

一.描述符是什么 描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议 __get__():调用一个属性时,触发 __set__():为一个属性赋值时,触发 __delete__():采用del删除属性时,触发 1 class Foo: #在python3中Foo是新式类,它实现了三种方法,这个类就被称作一个描述符 2 def __get__(self, instance, owner): 3 prin