描述器(三)

Day34 描述器(三)免费看

非数据描述器和数据描述器的访问顺序的本质、哪些案例是描述器实现的?属性装饰器property实现原理分析

08-22侠课岛    基础入门       

后端/后端/Python 由浅入深入门 9     0     206

总结

6.非数据描述器和数据描述器的访问顺序的本质

  • 事实上,实例属性的查找顺序并没有改变,依然是实例的__dict__中的属性优先被访问

  • 只是如果实例有属性是数据描述器的话,属性会被__dict__字典移除,因此就会访问类的属性,造成了数据描述器优先访问的假象;

7.哪些案例是描述器实现的

  • 属性装饰器@property(),是通过数据描述器实现;

  • 类方法装饰器@classmethod和静态方法装饰器@staticmethod都是通过非数据描述器实现;

8.描述器演练

(1)@staticmethod的实现

静态方法装饰器@staticmethod装饰的方法被装饰成了StaticMethod类的实例,可以看做一个类变量,因此类和 类的实例都可以访问这个类变量,那么就会调用__get__方法,返回self.fn,也就是原生的方法对象,最后调用这个方法对象;

(2)@ClassMethod的实现

类方法的实现与静态方法类似,只是需要调用partial偏函数,将类提前作为参数传递;

9.属性装饰器property实现原理分析

  • Python内置的@property装饰器,把一个方法变成可以像属性那样,做取值用;

  • @data.setter装饰器,把一个方法变成可以像属性那样,作赋值用;

  • @propertydata.setter()同时使用,表示可读可写;

课外补充:

描述器中__get__返回值的问题:

__get__函数的三个参数:__get__(self, instance, owner),这三个参数的名称是可以改的,但是一般都保持这样的名字,很容易看得出来这三个参数的意义。

我们可以如下理解__get__函数,当访问该类某个属性的时候,程序就会自动运行这个__get__函数,通过这个函数来访问类的变量,这个函数可以在里面写各种代码逻辑,它可以不写返回值,但是如果这个时候我们没有返回值,也就是返回是空的,那就找不到属性。

如下例子中:我通过XKD2来访问XKD1中的变量属性,语法是:XKD2.x.course,就是XKD2中的x已经被赋值为XKD1()了,那么访问course的时候,就是访问XKD1里面的course,这个course是XKD1类变量,通过__get__返回self就可以把这个类所有的变量和方法都返回了,外部就很容易访问到,所以,返回self更加方便。而这个__init____get__这样的函数的self这个参数名字是可以修改的,你可以改为self2,结果是一样的,实际上就是这个参数就是指向自身的类的意思,用self更加好理解。

除了这样,如果我们没有定义__get__函数,那么这个变量也是可以直接访问的,就是我们之前说的访问属性的基本语法,加入__get__就是是描述器做法,我们可以在访问属性之前,做一些事情,比如:我写好了这个类,规范返回course值为python1、python2这样,但是有一天,我这个类的逻辑改变了,在内部,course这个变量的值已经变为python3、python4了,那么我们就可以通过这个__get__函数去做一些逻辑处理,使得返回给外部的数据依然是python1、python2,这样就可以避免外部调用我的这个类的程序的人不需要改动他的程序,也不影响外部已有的功能。

如下图所示:我的course值初始为Python3了,然后我在__get__中做了一个简单三元运算判断,如果是为Python3,那么就会替换为Python1返回给外部。

同样的,__set__函数我们也可以做一些逻辑处理的,set相当于是设置数据,如设置数据的时候,可以进行数据的验证等。

本教程图文或视频等内容版权归侠课岛所有,任何机构、媒体、网站或个人未经本网协议授权不得转载、转贴或以其他方式复制发布或发表。

评价

9

本课评分:
  •     非常好
难易程度:
  •     适中的

内容目录



|
教程
粉丝
主页

签到有礼

已签到2天,连续签到7天即可领取7天全站VIP

  • 1
    +2 金币
  • 2
    +3 金币
  • 3
    +5 金币
  • 6
    +7 金币
  • 5
    +6 金币
  • 4
    暖心福利
    自选分类VIP ×1天
  • 7
    惊喜大礼

    自选分类VIP ×3天 +20金币
  • 持续签到 +8 金币

金币可以用来做什么?