6 [面向对象]-property
1、特性(property)
什么是特性property
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)
成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
体质指数(BMI)=体重(kg)÷身高^2(m)
EX:70kg÷(1.75×1.75)=22.86
(1)添加属性
class People: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height p = People('alex', 60, 1.80) p.bmi = p.weight / (p.height ** 2) print(p.bmi)
18.51851851851852
(2)通过方法返回
class People: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height def bmi(self): return self.weight / (self.height ** 2) p = People('alex', 60, 1.80) # p.bmi = p.weight / (p.height ** 2) # print(p.bmi) # 属性 print(p.bmi()) # 方法
(3)方法当做属性调用
class People: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height @property def bmi(self): return self.weight / (self.height ** 2) p = People('alex', 60, 1.80) # p.bmi = p.weight / (p.height ** 2) # print(p.bmi) # 属性 # print(p.bmi()) # 方法 print(p.bmi) # 类的特征方法转换为类的数据属性,调用的时候 p.bmi = 3333 # 不能赋值,不是真的数据属性
2、为什么要用property
class People: def __init__(self, name): self.__name = name @property def name(self): return self.__name p = People('alex') print(p.name) # 数据属性 p.name = 'ALEX'
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
除此之外,看下
ps:面向对象的封装有三种方式: 【public】 这种其实就是不封装,是对外公开的 【protected】 这种封装方式对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开 【private】 这种封装对谁都不公开
python并没有在语法上把它们三个内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现
class People: def __init__(self, name): self.__name = name @property def name(self): return self.__name @name.setter def name(self, name): if not isinstance(name, str): print('名字必须是字符串类型') return self.__name = name @name.deleter def name(self): print('不允许删除') p = People('alex') print(p.name) # property 数据属性 p.name = 14 # name.setter 修改的时候,限定 p.name = 'jack' print(p.name) del p.name # name.deleter 删除的时候,限定