首页 > 编程语言 > 详细

python基础-面向对象(二十四)面向对象进阶(十二)装饰器和描述符融合-自定义property

时间:2020-12-18 10:05:26      阅读:37      评论:0      收藏:0      [点我收藏+]

1.装饰器和描述器融合:一个类,既是装饰器也是描述器。是很多高级库和框架的重要工具之一

class Discr:  # Discr是装饰器同时也是个描述器
    def __init__(self, func):
        self.func = func
        # print(func) #func 是传进来的area方法

    def __get__(self, instance, owner):
        return self.func(instance)  # instance是对象test1


class Test:
    def __init__(self, length, width):
        self.lenth = length
        self.width = width

    @Discr  # area=Discr(area) area被装饰器代理了,Discr是装饰器同时也是个描述器
    def area(self):
        return self.width * self.lenth


test1 = Test(2, 5)
print(test1.area)
‘‘‘area方法被Discr(area)代理了,同时,Discr(area)也是实例化,会执行__init__。
它也是描述符,会调用__get__‘‘‘

 

技术分享图片

 

 上面完成了一个自定义的property。实例调用没问题,类调用还会报错,修改后如下

class Discr:  # Discr是装饰器同时也是个描述器
    def __init__(self, func):
        self.func = func
        # print(func) #func 是传进来的area方法

    def __get__(self, instance, owner):
        if instance is None:#类调用,instance为空
            return self
        return self.func(instance)  # instance是对象test1


class Test:
    def __init__(self, length, width):
        self.lenth = length
        self.width = width

    @Discr  # area=Discr(area) area被装饰器代理了,Discr是装饰器同时也是个描述器
    def area(self):
        return self.width * self.lenth


test1 = Test(2, 5)
# print(test1.area)
print(Test.area)
‘‘‘area方法被Discr(area)代理了,同时,Discr(area)也是实例化,会执行__init__。
它也是描述符,会调用__get__‘‘‘

2.实现延迟计算,或者说缓存

方法运行有可能代码很长,一次运行后要把结果保存起来,下次直接读取。那么存到哪里呢?字典!

class Discr:  # Discr是装饰器同时也是个描述器
    def __init__(self, func):
        self.func = func
        # print(func) #func 是传进来的area方法

    def __get__(self, instance, owner):
        if instance is None:#类调用,instance为空
            return self
        res=self.func(instance)  # instance是对象test1
        setattr(instance,self.func.__name__,res)
        print(from __get__)
        return res
    # def __set__(self, instance, value):
    #     pass


class Test:
    def __init__(self, length, width):
        self.lenth = length
        self.width = width

    @Discr  # area=Discr(area) area被装饰器代理了,Discr是装饰器同时也是个描述器
    def area(self):
        return self.width * self.lenth


test1 = Test(2, 5)
print(test1.area)
print(test1.__dict__)
print(test1.area)

‘‘‘__dict__有了,下次直接读取,实例属性优先级>非数据属性
若有__set__,在__dic__保存结果不成功‘‘‘

技术分享图片

 

python基础-面向对象(二十四)面向对象进阶(十二)装饰器和描述符融合-自定义property

原文:https://www.cnblogs.com/liaoyifu/p/14152766.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!