property

# property装饰器

# python提供了一个装饰器property,用来绑定给对象的方法伪造一个数据属性,
# 可以将类中的函数“伪装成”对象的数据属性,对象在访问该特殊属性时会触发功能的执行,然后将返回值作为本次访问的结果


"""案例一
BMI指数是用来衡量一个人的体重与身高对健康影响的一个指标,计算公式为
体质指数(BMI)=体重(kg)÷身高^2(m)
EX:70kg÷(1.75×1.75)=22.86

成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
"""


class People:
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height

    # 定义函数的原因1:
    # 1、从bmi的公式上看,bmi应该是触发功能计算得到的
    # 2、bmi是随着身高、体重的变化而动态变化的,不是一个固定的值
    #    说白了,每次都是需要临时计算得到的

    # 但是bmi听起来更像是一个数据属性,而非功能
    @property
    def bmi(self):
        return self.weight / (self.height ** 2)


obj = People('aa', 70, 1.83)
print(obj.bmi)  # 触发方法bmi的执行,将obj自动传给self,执行后返回值作为本次引用的结果


# 使用property有效地保证了属性访问的一致性。另外property还提供设置和删除属性的功能
# 案例二
class Foo:
    def __init__(self, val):
        self.__NAME = val

    @property
    def name(self):
        return self.__NAME

    @name.setter
    def name(self, value):
        if not isinstance(value, str):  # 在设定值之前进行类型检查
            raise TypeError('%s must be str' % value)
        self.__NAME = value  # 通过类型检查后,将值value存放到真实的位置self.__NAME

    @name.deleter
    def name(self):
        raise PermissionError('Can not delete')


f = Foo('lili')
# 人正常的思维逻辑
print(f.name)
f.name = 111  # 触发name.setter对应的函数name(f,123),抛出异常TypeError
del f.name  # 触发name.deleter对应的函数name(f),抛出异常PermissionError

posted @ 2021-01-26 15:16  啦啦哦  阅读(174)  评论(0编辑  收藏  举报