洗礼灵魂,修炼python(46)--巩固篇—如虎添翼的property
@property
在前面装饰器一章中,提过一句话,装饰器也可以用于类中,确实可以的,并且python的类也内置了一部分装饰器。并且在前两章的hasattr等四个内置方法中,也说过其用法很类似装饰器,到底在类中可以用装饰器不呢?还有具体有哪些内置的装饰器呢?还记得property吗?之前有个例子里,在类里定义好方法后,再用property就可以通过属性设置属性
先看一个普通的类
当我们设置property属性后:
但其实你发现了,其实使用property与否并没有什么两样的,目前确实是这样,在前面我也没有细说,只是说了用法,但你知道python3是对python2的功能的增删整合而来,那么python3里,照刚才的用法,property应该没有任何用处啊,但为什么还留着,是的,表面上来并没有什么区别,不过当在前面加上符号【@】之后,@property就牛逼得不要不要的了。
具体是怎么的呢?老套路,不急,现在有一个场景,公司里由于负责运维的员工请假回家了,现在老板让你暂时顶一下运维的班,但是现在由于一些原因,需要简单的查询和修改员工信息,把员工档案归类一下,老板让你负责跟进一下这一块。你打开员工文档查看那后,写下一个简单的类
class data:
def __init__(self,name,age,sex,birthday,post):
self.name=name
self.age=age
self.sex=sex
self.birthday=birthday
self.post=post
def get_somedata(self):
print('姓名:',self.name)
print('年龄:',self.age)
print('性别:',self.sex)
print('出生年月:',self.birthday)
print('职位:',self.post)
def set_name(self,name):
if not isinstance(name,str):
raise TypeError('name must be a str')
else:
self.name=name
def set_age(self,age):
if not isinstance(age,int):
raise TypeError('age must be a int')
elif age<0 or age>60:
raise ValueError('age must between 0 ~ 100!')
else:
self.age=age
并导入你自己的员工信息测试:
代码初步没什么问题,你让老板过来看了下,老板说,可以,但能不能再优化一下,比如尽量的减少方法,减少代码量,但是功能依然相同,你考虑再三,开始尝试使用高阶用法,@property,先查阅想关资料,看到property的相关用法:
乍一看没看明白,反正一脸蒙蔽,然后通过仔细查阅python官方文档后有所了解,调试代码之后:
发现报错了,提示没有类型,也就是None,空了,我们知道当方法的调用结果是print的话,返回的就是空,那看来@property必须有返回值才行
再次调试:
标记蓝色框的是必须是这种格式,@property装饰的什么方法,第二次使用修改setter必须使用被装饰的方法,然后两次被装饰的方法名必须相同。被装饰的方法已经变为属性,不用加()实例化调用了。
至于报错,再看看官方文档:
官方文档里只能修改一个参数,那么只得一个一个改了:
做了一个简单的修改名字的代码,没问题了,如果需要全部的修改就得一个一个使用@property来修改了。并且还可以使用deltter删除操作。并且当方法被@property装饰时,默认拥有getter只读属性。所以可以对每个参数针对性的设置不同效果
像@property,在以后的开发中,很常见,和hasattr,getattr,setattr,delattr综合使用的话,那简直6到飞起啊,想怎么搞就怎么搞