7.12 property装饰器的使用
意义:本节介绍的装饰器可以让我们把函数属性做得像一个数据属性!
- 这里我们介绍以下装饰器:
- @property
- @func.setter
- @func.deleter
场景: 当一个数据属性需要通过计算或者处理才能得出的时候,我们需要用函数属性来计算, 这样,调用的时候用户需要调用方法来获得这个属性。 但是对于用户来说,函数属性是用来做事的而不是来获取数据属性的。 这种情况我们该怎么办呢?
这时,我们就可以在这个函数属性上加一个 @property 的装饰器来实现 函数属性→数据属性 的伪装
@property装饰器:
# BMI 体质指数计算例: bmi = 体重 / 身高的平方
class People:
def __init__(self, name, weight, height):
self.name = name
self.weight = weight
self.height = height
@property # 装饰器修饰bmi函数属性
def bmi(self): # 因为bmi只是一个对象的属性而不是对象的动作,我们不想用方法来调用。
return self.weight / (self.height ** 2) # 返回结果
p1 = People('a', 85, 1.78)
print(p1.bmi) # 如果没有@property装饰器,我们这里需要用p.bmi()来调用。
# 注意:bmi是个方法,所以不能直接赋值
# p.bmi = 3333 # 这个会报错:AttributeError。不过真想对这个方法进行修改,可以用setter,deleter装饰器重写该方法
@func.setter,@func.deleter装饰器:
class People:
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter # 设定用装饰器
def name(self, val):
if not isinstance(val, str):
print('名字必须是字符')
return
self.__name = val
@name.deleter
def name(self):
print('deleter')
del self.__name # 删除name属性
p1 = People('a')
print(p1.name)
p1.name = 'A' # 可以(似乎只能)用 = 来赋值,@setter
print(p1.name)
p1.name = 123 # 不符合类型会print
print(p1.__dict__)
del p1.name # 可以用del来删除, @deleter
print(p1.__dict__)
执行结果:
a
A
名字必须是字符
{'_People__name': 'A'}
deleter
{}