一个求BMI体质指数的例子,代码如下:
体质指数(BMI)= 体重 / 身高 **2
1 class People: 2 def __init__(self, name, weight, height): 3 self.name = name 4 self.weight = weight 5 self.height = height 6 7 p = People('alex', 75, 1.81) 8 9 p.bmi = p.weight / (p.height ** 2) 10 print(p.bmi) 11 12 结果为: 13 14 22.89307408198773
但是,这样不够灵活,我们对代码做下更改:
如下:
1 class People: 2 def __init__(self, name, weight, height): 3 self.name = name 4 self.weight = weight 5 self.height = height 6 7 def bmi(self): 8 return self.weight / (self.height ** 2) 9 10 p = People('alex', 75, 1.81) 11 12 # p.bmi = p.weight / (p.height ** 2) 13 print(p.bmi()) 14 15 结果为: 16 17 22.89307408198773
上述代码一定程度上提高了灵活性,但是用户的调用的时候是在调用一个方法区执行,能不能让用户感觉就向在调一个数据属性呢,答案是可以的,这就用到了property装饰器
如下:
1 class People: 2 def __init__(self, name, weight, height): 3 self.name = name 4 self.weight = weight 5 self.height = height 6 7 @property 8 def bmi(self): 9 return self.weight / (self.height ** 2) 10 11 p = People('alex', 75, 1.81) 12 13 # p.bmi = p.weight / (p.height ** 2) 14 # print(p.bmi()) 15 print(p.bmi) 16 17 结果为: 18 19 22.89307408198773
但是不能给p.bmi赋值,因为它说到底还是一个方法,
二、给一个方法赋值,
l例如:
1 class People: 2 def __init__(self, name): 3 self.__name = name 4 5 @property 6 def name(self): 7 return self.__name 8 9 @name.setter 10 def name(self, val): 11 if not isinstance(val, str): 12 print('名字必须是字符串类型') 13 return 14 self.__name = val 15 16 p = People('egon') 17 p.name = 'EGON' 18 print(p.name) 19 20 结果为: 21 22 EGON
这用到了name.setter 装饰器,这是在property装饰器的基础之上实现的
当然也可以删除
例如
1 class People: 2 def __init__(self, name): 3 self.__name = name 4 5 @property 6 def name(self): 7 return self.__name 8 9 @name.setter 10 def name(self, val): 11 if not isinstance(val, str): 12 print('名字必须是字符串类型') 13 return 14 self.__name = val 15 16 @name.deleter 17 def name(self): 18 print('deleter') 19 20 print('不允许删除') 21 22 p = People('egon') 23 # p.name = 'EGON' 24 # print(p.name) 25 26 del p.name 27 28 结果为: 29 30 deleter 31 不允许删除