python面向对象-封装

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
1
a = A()
1
a.get_val()
0
1
a.set_val(200)
1
a.get_val()
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
1
b = B()
1
b.get_val()
0
1
b.set_val(200)
1
b.get_val()
0
1
b.set_val(80)
1
b.get_val()
80
1
b.set_val(-50)
1
b.get_val()
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
1
c = C()
1
c.val
0
1
c.val = 20
1
c.val
20
1
c.val = -30
1
c.val
0

如上,现在想设置__val的值可直接像调用类属性的方式,比较简洁。

在使用property装饰器时,@property本身又会创建另一个装饰器,在这里就是@val.setter,其内部的原理不是太清楚,目前只要记住它的用法即可。

总结一下:

使用@property装饰的函数时,目的是想获取一个值,而使用@val.setter装饰器时是重新设置一个值,这里的val是被@property装饰函数的名称,两个装饰器装饰的函数名称必须要相同。使用@property装饰器能让调用更简洁。

文章目录
  1. 1. @property
|