# 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