作为一名python的运用者,你能够运用python有一段时间了,然则关于python中的描述符却未必运用过,接下来是对描述符运用的引见
场景引见
为了引入描述符的运用,我们先设想一个异常简朴的类:
class Product(): def __init__(self,name,quantity,price): self.name = name self.quantity = quantity self.price = price
这是一个商品类,存储该商品的称号,数目与价钱。
关于一件商品,我们平常会希冀它的数目和价钱不会是负值,为了防备这类状况,我们能够在初始化的时刻加一些推断,比方下面如许:
class Product(): def __init__(self,name,quantity,price): self.name = name if quantity<0: raise ValueError('quantity must be >= 0') self.quantity = quantity if quantity<0: raise ValueError('price must be >= 0') self.price = price
然则如许还会有一个弊病就是如许的推断只是加在了初始化的时刻,然后在以后对类的实例的属性举行赋值的时刻照样没法保证赋的值是大于0 的
因而我们能够运用‘特征’来处理这个题目:
class Product(): def __init__(self,name,quantity,price): self.name = name self.quantity = quantity self.price = price @property def quantity(self): return self._quantity @quantity.setter def quantity(self,value): if value < 0: raise ValueError('quantity must be >= 0') else: self._quantity = value @property def price(self): return self._price @price.setter def price(self, value): if value < 0: raise ValueError('price must be >= 0') else: self._price = value book = Product('mybook',6,30) print(book.quantity)
这里的@property和@quantity.setter是两个装潢器,它能够设置属性的读与写,就相当于读写属性,但实际上是实行一个函数,细致有关特征的引见,能够再自行查找,这里重要是为了引出描述符。
经由过程特征,能够完成为属性赋值时增加推断。然则当一个类中有更多的属性,许多属性一样须要增加非负数赋值的搜检的时刻,运用特征这类体式格局就会显得过于累坠,会有许多的代码反复,也会增加许多装潢器,这时候就能够运用描述符来处理这个题目。
运用描述符
起首看一下描述符的观点
描述符就是一个“绑定行动“的对象属性,在描述符协定中,它能够经由过程要领充写属性的接见。这些要领有get(),set(),delete().假如这些要领中任何一个被定义在一个对象中,这个对象就是一个描述符
(这几个要领是特别要领,双下划线由于转换未显现)
我们先把上文中的商品类根据运用描述符举行修正:
class NotNegative(): def __init__(self,name): self.name = name def __set__(self, instance, value): if value < 0: raise ValueError(self.name+' must be >= 0') else: instance.__dict__[self.name] = value class Product(): quantity = NotNegative('quantity') price = NotNegative('price') def __init__(self,name,quantity,price): self.name = name self.quantity = quantity self.price = price book = Product('mybook',2,5)
NotNegative是描述符类,它是Product类的类属性
在该例子中,假如实行book.quantity=3,诠释器会先查找实例属性,发明有quantity属性,然则诠释器又发明一样有一个类属性是描述符,因而诠释器终究会挑选走描述符这条路。然后由于是描述符,因而会实行描述符中的set特别要领。
描述符中的set特别要领的参数有为
self :是描述符实例
instance :是相当于例子中的实例book
value :就是要给予的值
由于这些属性关于取值没有什么特别的请求所以例子中没有完成get特别要领。
get要领一样有3个参数self, instance, owner。self,instance与set中的雷同,owner为例子中的Product类
接下来重要看一下描述符set要领中else部份举行的操纵
instance.__dict__[self.name] = value
经由过程挪用book实例的dict,直接为dict中的属性赋值,这也是参数中传入实例的一个重要原因。由于描述符对象是作为类属性存在,所以能够会有许多个该类的对象接见,为了防备属性的掩盖,直接存入实例的属性中是稳健的。但这里不能为属性赋值的体式格局,不然就会堕入死循环当中。
关于数据描述符与非数据描述符,一个类,假如只定义了 get() 要领,而没有定义 set(), delete() 要领,则以为黑白数据描述符; 反之,则成为数据描述符。
末了,本文是对描述符的运用做了简朴的引见与解说,如需越发深切相识能够参考《流通的Python》属性描述符部份
以上就是Python描述符的用法引见(附示例)的细致内容,更多请关注ki4网别的相干文章!