之前文章我们介绍了class的一些通用功能,比如类属性/类方法/实例属性/实例方法等,之前的属性可以直接修改和访问(设置私有属性,不能直接访问,可通过对象名._[类名][属性名]的方式访问),没有一些权限的控制逻辑。
本章主要介绍属性装饰器@property(还有实现相同功能的property()函数),该装饰器可把函数当成属性使用,可直接访问,访问时不用添加双括号(),并可对其进行一些修改和删除的权限控制。
@property装饰器
未使用@property之前,我们一般定义类属性和实例属性如下:
定义一个5座汽车的类Car,初始化三个参数品牌,颜色,性价比。
class Car():
persons = 5
def __init__(self,brand,color,cost_performance):
self.brand = brand
self.color = color
self.cost_performance = cost_performance
#修改Car类的类属性值为7座
Car.persons = 7
print(f'汽车乘坐人数 :{Car.persons}')
#对Car类实例化,带入品牌等参数
Mercedes_Benz = Car('GLC260','black','不高')
#获取品牌参数
print(f'汽车品牌 :{Mercedes_Benz.brand}')
#修改Mercedes_Benz实例化属性-品牌
Mercedes_Benz.brand = 'bmwx3'
print(f'汽车品牌 :{Mercedes_Benz.brand}')
打印结果如下:
汽车乘坐人数 :7
汽车品牌 :GLC260
汽车品牌 :bmwx3
我们使用@property属性装饰器改造下brand属性的获取/修改和删除功能,定义一个函数carbrand返回self.brand。
@property
def carbrand(self):
return self.brand
@carbrand.setter
def carbrand(self,brand):
self.brand = brand
print(f'设置实例属性品牌为{self.carbrand}')
@carbrand.deleter
def carbrand(self):
print('不能删除实例属性')
raise False
- @carbrand.setter装饰器: 当对carbrand属性修改赋值时执行该函数
- @carbrand.deleter装饰器:当对carbrand属性删除时执行该函数
我们访问和修改,删除属性看下是什么结果
Mercedes_Benz = Car('GLC260','black','不高')
#修改属性值
Mercedes_Benz.carbrand = 'bmwx3'
print(f'汽车品牌 :{Mercedes_Benz.carbrand}')
#删除属性值
del Mercedes_Benz.carbrand
结果显示执行了被@carbrand.setter装饰的函数,被@carbrand.deleter装饰的函数
#打印结果如下
设置实例属性品牌为bmwx3
汽车品牌 :bmwx3
不能删除实例属性
Traceback (most recent call last):
File "/Users/htsc/Desktop/test.py", line 204, in <module>
del Mercedes_Benz.carbrand
File "/Users/htsc/Desktop/test.py", line 181, in carbrand
raise False
TypeError: exceptions must derive from BaseException
property函数
使用property()函数也可以实现类似@property的功能,将上述例子改造如下:
def carbrand(self):
return self.brand
def carbrand_setter(self, brand):
self.brand = brand
print(f'设置实例属性品牌为{self.brand}')
def carbrand_deleter(self):
print('不能删除实例属性')
raise False
#定义property()函数赋值给newbrad
newbrand = property(carbrand, carbrand_setter, carbrand_deleter,'汽车品牌')
property()函数是一个内置函数,可传入四个参数,分别对应getter方法、setter方法、deleter方法和docstring。其中,getter方法用于获取属性值,setter方法用于设置属性值,deleter方法用于删除属性,docstring则是该属性的文档说明。
同样我们访问/修改和删除newbrand属性,看下结果
Mercedes_Benz = Car('GLC260','black','不高')
#获取属性
print(f'汽车品牌 :{Mercedes_Benz.newbrand}')
#修改属性
Mercedes_Benz.newbrand = 'bmwx3'
print(f'修改汽车品牌 :{Mercedes_Benz.newbrand}')
#删除属性
del Mercedes_Benz.newbrand
结果如下:跟@property的结果一样
汽车品牌 :GLC260
设置实例属性品牌为bmwx3
修改汽车品牌 :bmwx3
不能删除实例属性
Traceback (most recent call last):
File "/Users/htsc/Desktop/test.py", line 218, in <module>
del Mercedes_Benz.newbrand
File "/Users/htsc/Desktop/test.py", line 204, in carbrand_deleter
raise False
TypeError: exceptions must derive from BaseException
共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”
-----指水滴不断地滴,可以滴穿石头;
-----比喻坚持不懈,集细微的力量也能成就难能的功劳。
----感谢读者的阅读和学习,谢谢大家。