今天这个问题是一定要弄清楚的,不搞定誓不罢休
复习了这个Python描述符啊!!!感觉自己遇到了一些问题想给大家分享一下
---------------------------------------------
-
什么是描述符
-
描述符的参数到底是什么鬼
-
描述符的分类
-
描述符的优先级
----------------------------------------------
开练开练
1.什么是描述符
描述符就是将某种特殊类型的类的实例指派给另一个类的类的属性(挖槽!!!什么鬼,好模糊的概念)
描述符就是一个“绑定行为“的对象属性,在描述符协议中,它可以通过方法充写属性的访问。这些方法有get(),set(),delete().如果这些方法中任何一个被定义在一个对象中,这个对象就是一个描述符(额!!!好像有点清楚)
描述符就是对属性(或其他对象)的获得、删除、赋值的一种描述(哎呀哇!!不错噢,有点意思)
现在各位靓仔靓妹们对描述符一定的爱的初印象了(那我们接着看看)
描述符的内置方法(也就是属性(或其他对象)的方法)
__get__(self,instance,owner) 该方法用于访问属性,它返回属性的值
__set__(self,instance,value) 该方法用于设置属性的值,不返回值
__delete__(self,instance) 该方法用于删除属性,不返回任何内容
如果一个类中包含了这三种方法(__get__,__set__,__delete__)之一或者全部,那么这个类就是描述符
2.描述符的参数到底是什么鬼
self是指被实例化的对象
instance表示涵盖实例对象的类,被实例的对象
owner是指涵盖实例对象的类
value是指传入(设置)的值
(啊啊啊!!头爆了,都是些什么鬼!!不怕,直接上例子说明)
>>> class My:
def __get__(self,instance,owner):
print('getting....')
def __set__(self,instance,value):
print('setting....')
def __delete__(self,instance):
print('deleting....')
>>> class Test:
x = My()
>>> test = Test()
这时My是一个描述符(这个大家应该都知道吧)
此时该描述符的方法里的参数到底是什么意思呢???
self ==>> x(是指被实例化的对象)
instance ==>> test(表示包含实例描述符的类,被实例的对象)
owner ==>> Test(是指涵盖实例对象的类)
【到这样基本的含义都搞定啦!!!接下来搞个活物..】
例子:摄氏度和华氏度的转换
##Celsius代表摄氏度的类
##Fahrenheit代表华氏度的类
class Celsius:
def __init__(self,value= 26.0): 这里设置了摄氏度(value)的默认值
self.value = float(value)
def __get__(self,instance,owner):
return self.value
def __set__(self,instance,value):
self.value = float(value)
class Fahrenheit:
def __get__(self,instance,owner):
return instance.cel * 1.8 + 32
def __set__(self,instance,value):
instance.cel = (float(value)-32)/18 这里一设置了cel属性的值,就会跳到Celsius的
__set__方法,然后更新Celsius里的value值
class Temperature:
cel = Celsius() 这里是不是有一点蒙,其实cel就是个属性,而Celsius()对应的是这个属性的获得、设置的方法
fah = Fahrenheit() 这里也是如此
>>> C = Temperature()
>>> T = Temperature()
>>> T.cel 获得方法(触发 Celsius的__get_方法_并返回初始值)
26.0
>>> T.cel = 29 设置cel的值(即触发 Celsius的__set__方法)
>>> T.fah 获得fah(华氏度)触发Fahrenheit的__get__方法并将T.cel带入运算后返回
84.2
>>> T.fah = 88 设置fah的值(即触发Fahrenheit的__set__方法【方法里有个cel属性的赋值
即又跳转到Celsius的__set__方法】)
>>> T.cel 获得摄氏度,触发Celsius的__get_方法_并返回初始值
3.111111111111111
到这里可能不懂的靓仔靓女要花多点时间去琢磨一下【特别是不要忘记描述符的参数还有描述符的行为(即方法)】
3.描述符的分类
如果一个类中包含了这三种方法(__get__,__set__,__delete__)之一或者全部
那么这个类就是描述符(就是它,这个家伙)
那么这三种方法当然也就是魔法方法啦(你会发现,我都没有调用这个方法,怎么突然就帮我实现了,这就是魔法方法啦)
【 “=” 就是自动调用__set__方法】
【“delete” 就是自动调用__delete__方法】
【“.”调用属性就是自动调用__get__方法】
(再来一遍:魔法方法会自动调用噢!!!)
那么描述符又分为数据描述符和非数据描述符
非数据描述符:不包含__set__方法的类
数据描述符:含有__set__和__get__方法等的类
4.描述符的优先级
那么讲了那么多!描述符的优先级是什么呢(从高到低)?
只要调用属性【会无条件执行 __getattribute__()】
- 类属性
- 数据描述符: __get__ __set__
- 实例属性
- 非数据描述符
- 找不到属性触发 __getattr__(__getattr__也是一个魔法方法,用来当找不到属性的时候执行的东西,一般抛出一个异常)
如果对有优先级有什么不理解的可以观看这个链接视频哦(https://haokan.baidu.com/v?pd=wisenatural&vid=11831538515432052030)【我也是从这里受到启发的(6分钟的事)】
到这样就结束啦!哈哈哈哈,相信这些需要自己消化一段时间啦
最后补充一个知识点
每个对象均具备的属性__dict__
该作用是存放本对象的属性,key即为属性名,value即为属性的值,形式为{attr__key:attr_value},为字典类型
----------------------------------------------------------------------------------------------------------
不好意思各位大佬,写了这么这么长的文章【一般太长的我都不爱看哈哈哈哈哈】
如果对你有帮助的话,就留下你的赞吧