码迷,mamicode.com
首页 > 其他好文 > 详细

通过描述符自定制@property的功能

时间:2018-08-14 00:21:39      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:方法   self   nbsp   通过   调用   实例   属性   print   结果   

# 通过描述符自定制@property的功能

# 原始通过@property实现的功能:将类中定义的函数属性,通过装饰器@property将其封闭成数据属性

class Room:
    def __init__(self, name, width, length):
        self.name = name
        self.width = width
        self.length = length

    @property
    def area(self):
        return self.width * self.length


r1 = Room(厨房, 10, 4)
print(r1.area)


# 通过描述符与装饰器自定制@property的功能

class Lazyproperty:  # 定义描述符的类
    def __init__(self, func):  # 初始化时接收传入的方法进行保存
        self.func = func

    def __get__(self, instance, owner):
        if instance is None:    # 解决直接用类调用属性时传不了实例而报错的问题
            return self
        res = self.func(instance)
        setattr(instance, self.func.__name__, res)  # 将res放入实例的字典中,如果下次再调用,根据优先级实例属性高于非数据描述符,实例的属性字典中有就直接从实例的属性字典中找了
        return res  # 返回实例对象调用父类方法的结果,instance代表实例


class Room2:
    def __init__(self, name, width, length):
        self.name = name
        self.width = width
        self.length = length

    @Lazyproperty   # area=Lazyproperty(area) 使用装饰器的这一步就相当于对area属性指定了描述符,给Room2添加了一个类属性
    def area(self):
        return self.width * self.length

r2 = Room(厨房, 10, 4)
# 实例调用area
print(r2.area)  # 从r2中先找有没有area属性,没有从父类Room2中找,找到后发现是非数据描述符,就触发了__get__方法
# 类调用area
print(Room2.area)   # 由于__get__方法的接收参数需要一个实例,这里是用类调用的,所以会传None过去,因此会报错

 

通过描述符自定制@property的功能

标签:方法   self   nbsp   通过   调用   实例   属性   print   结果   

原文地址:https://www.cnblogs.com/dangrui0725/p/9471820.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!