Press "Enter" to skip to content

【数据挖掘】Python的描述器

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

 

01

 

背景

 

很多Python库中都会出现描述器(descriptor)的身影,Python内置的 staticmethod, classmethod, property,super
等方法也都是描述器。了解描述器协议对于我们理解这些对象的行为会有很大帮助。

 

02

 

 

通常,描述符是具有描述符协议中方法之一的属性值。这些方法是get(),set()和delete()。如果为属性定义了那些方法中的任何一种,则称其为描述符。

 

如果一个对象定义了以下三个方法中的任意一个,那幺这个对象就可以被称之为描述器:

 

__set__(**)
__get__(**)
__delete__(**)

 

03

 

分类

 

如果对象定义set()或delete(),则将其视为数据描述符。仅定义get()的描述符称为非数据描述符(它们通常用于方法,但也可以用于其他用途)。

 

描述器又可分为数据描述器(data descriptor)和非数据描述器(non-data descriptor),只有 *get*
方法的对象被称为非数据描述器(non-data desriptor),其他的都称为数据描述器(data descriptor)。

 

04

 

使用

 

下面通过一个例子来展示描述器是怎幺使用的。

 

class PositiveNumber(object):
 
 
    def __init__(self, name, value):
        self.name = name 
        self._value = value
 
    def __get__(self,  obj, dtype):
        return self._value  
 
    def __set__(self,  obj, value):
        if value

上述代码中的number便是一个描述器。一般来说,描述器是作为另一个对象的属性来出现的:

 

class PositiveNumber(object):
 
 
    def __init__(self, name, value):
        self.name = name 
        self._value = value
 
    def __get__(self,  obj, dtype):
        print("call `__get__` method")
        print("obj : {}".format(obj))
        print("dtype: {}".format(dtype))
        return self._value  
 
    def __set__(self,  obj, value):
        if value

这样,描述器number作为Apple类的一个属性,在创建新的Apple实例apple=Apple(10)的时候,self.price = 10便会触发描述器的__set__, 监测price参数是否为正数,并在不符合条件的时候引发异常。

 

同样,当我们执行print(apple.price)时,dot操作符会触发描述器的__get__方法,执行删除操作的时候会触发描述器的__delete__方法。

 

这样,我们就通过定义描述器的方式,改变了对象的属性在赋值、删除和访问时的默认行为,描述器的功能正在于此。

 

05

 

扩展

 

1.Python内置的 staticmethod, classmethod, property,super
等方法也都是描述器,具体的时候可以查看相应的文档

 

2.实例和类的dotted lookup 优先级有所不同,所以描述器在被类和实例调用时的行为也略有不同,参见Python文档。

 

参考资料

 

https://docs.python.org/zh-cn/3/howto/descriptor.html

 

https://zhuanlan.zhihu.com/p/52708890

 

Be First to Comment

发表评论

邮箱地址不会被公开。 必填项已用*标注