python学习笔记之面向对象-封装
@property
先来看一个例子,如下:
1 2 3 4 5 6 7 8 9 class A : def __init__ (self ): self.__val = 0 def get_val (self ): return self.__val def set_val (self,x ): self.__val = x
0
200
上边的这个类A,实现了通过调用get_val
方法可获取类私有变量__val
的值,通过set_val
方法可以修改__val
变量的值,但对所修改的值没有限定范围,如果需要对赋值限定一个范围,那该怎么办呢? 改进上边的类,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class B : def __init__ (self ): self.__val = 0 def get_val (self ): if self.__val < 0 : return 0 return self.__val def set_val (self,x ): if isinstance(x,(int,float)) and x >= 0 and x <= 100 : self.__val = x else : self.__val = 0
0
0
80
0
上边的类B中set_val
方法加了判断条件,只允许设置0~100的数,这样就不能随心所欲的设置__val
的值了,但如b.set_val(80)
这样的调用略显复杂,能不能像访问类属性一样来访问这里的方法? propery这个装饰器就能实现,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class C : def __init__ (self ): self.__val = 0 @property def val (self ): if self.__val < 0 : return 0 return self.__val @val.setter def val (self,x ): if isinstance(x,(int,float)) and x >= 0 and x <= 100 : self.__val = x else : self.__val = 0
0
20
0
如上,现在想设置__val
的值可直接像调用类属性的方式,比较简洁。
在使用property
装饰器时,@property
本身又会创建另一个装饰器,在这里就是@val.setter
,其内部的原理不是太清楚,目前只要记住它的用法即可。
总结一下:
使用@property
装饰的函数时,目的是想获取一个值,而使用@val.setter
装饰器时是重新设置一个值,这里的val
是被@property
装饰函数的名称,两个装饰器装饰的函数名称必须要相同。使用@property
装饰器能让调用更简洁。