在面向对象编程中,公开的数据成员可以在外部随意访问和修改,很难控制用户修改时新数据的合法性。解决这一问题的常用方法是定义私有数据成员,然后设计公开的成员方法来提供对私有数据成员的读取和修改操作,修改私有数据成员时可以对值进行合法性检查,提高了程序的健壮性,保证了数据的完整性。属性结合了公开数据成员和成员方法的优点,既可以像成员方法那样对值进行必要的检查,又可以像数据成员一样灵活的访问。
Python 2.x中属性的实现有很多不如人意的地方,在Python 3.x中,属性得到了较为完整的实现,支持更加全面的保护机制。如果设置属性为只读,则无法修改其值,也无法为对象增加与属性同名的新成员,同时,也无法删除对象属性。例如:
>>> class Test:
def __init__(self, value):
self.__value = value #私有数据成员
@property #修饰器,定义属性,提供对私有数据成员的访问
def value(self): #只读属性,无法修改和删除
return self.__value
>>> t = Test(3)
>>> t.value
3
>>> t.value = 5 #只读属性不允许修改值
Traceback (most recent call last):
File "<pyshell#151>", line 1, in <module>
t.value = 5
AttributeError: can't set attribute
>>> t.v=5 #动态增加新成员
>>> t.v
5
>>> del t.v #动态删除成员
>>> del t.value #试图删除对象属性,失败
Traceback (most recent call last):
File "<pyshell#152>", line 1, in <module>
del t.value
AttributeError: can't delete attribute
>>> t.value
3
下面的代码则把属性设置为可读、可修改,而不允许删除。
>>> class Test:
def __init__(self, value):
self.__value = value
def __get(self): #读取私有数据成员的值
return self.__value
def __set(self, v): #修改私有数据成员的值
self.__value = v
value = property(__get, __set) #可读可写属性,指定相应的读写方法
def show(self):
print(self.__value)
>>> t = Test(3)
>>> t.value #允许读取属性值
3
>>> t.value = 5 #允许修改属性值
>>> t.value
5
>>> t.show() #属性对应的私有变量也得到了相应的修改
5
>>> del t.value #试图删除属性,失败
Traceback (most recent call last):
File "<pyshell#152>", line 1, in <module>
del t.value
AttributeError: can't delete attribute
当然,也可以将属性设置为可读、可修改、可删除。
>>> class Test:
def __init__(self, value):
self.__value = value
def __get(self):
return self.__value
def __set(self, v):
self.__value = v
def __del(self): #删除对象的私有数据成员
del self.__value
value = property(__get, __set, __del) #可读、可写、可删除的属性
def show(self):
print(self.__value)
>>> t = Test(3)
>>> t.show()
3
>>> t.value
3
>>> t.value = 5
>>> t.show()
5
>>> t.value
5
>>> del t.value
>>> t.value #相应的私有数据成员已删除,访问失败
Traceback (most recent call last):
File "<pyshell#165>", line 1, in <module>
t.value
File "<pyshell#157>", line 6, in __get
return self.__value
AttributeError: 'Test' object has no attribute '_Test__value'
>>> t.show()
Traceback (most recent call last):
File "<pyshell#166>", line 1, in <module>
t.show()
File "<pyshell#157>", line 17, in show
print(self.__value)
AttributeError: 'Test' object has no attribute '_Test__value'
>>> t.value =1 #为对象动态增加属性和对应的私有数据成员
>>> t.show()
1
>>> t.value
1
稿源:微信定制开发www1.qixoo.com