python2和Python3的属性的处理和实现不一样,内部实现有较大差异,本文属性指的是狭义的概念。
一.Python2中的属性
在Python2中属性使用@property或者property来声明,但是属性并没有真正意义上实现过,也没有提供应有的保护机制。为对象增加新成员时,python2中原来的私有变量没有改变,只是动态的增加了新成员,隐藏了定义的属性。
>>> class A:
def __init__(self,v):
self.__v = v
@property
def v(self):
return self.__v
>>> a = A(3)
>>> a.v
3
>>> a.v = 5#动态的添加了新成员,隐藏了定义的属性
>>> a.v
5
>>> a._A__v#原来的私有变量没改变
3
下面的代码实际上也是增加了新成员,隐藏了已有的属性
>>> class A:
def __init__(self,v):
self.__v = v
def __get(self):
return self.__v
def __set(self,v):
self.__v = v
v = property(__get,__set)
def show(self):
print self.__v
def show(self):
print self.__v
>>> t = A(3)
>>> t.v
3
>>> t.v +=2#动态添加新成员
>>> t.v#访问新成员
5
>>> t.show()#访问私有成员
3
>>> del t.v#删除刚添加的新成员
>>> t.v#访问原来的属性
3
>>> del t.v#试图删除属性
Traceback (most recent call last):
File "<pyshell#200>", line 1, in <module>
del t.v
AttributeError: A instance has no attribute 'v'
>>> t.v
3
>>> del t._A__v#删除私有成员
>>> t.v#访问属性,但是私有成员已经不存在了
Traceback (most recent call last):
File "<pyshell#203>", line 1, in <module>
t.v
File "<pyshell#192>", line 6, in __get
return self.__v
AttributeError: A instance has no attribute '_A__v'
下面演示私有成员与普通成员之间的关系:
class A:
def show(self):
print self.a
print self.__b
>>> a = A()
>>> a.show()
Traceback (most recent call last):
File "<pyshell#210>", line 1, in <module>
a.show()
File "<pyshell#208>", line 3, in show
print self.a
AttributeError: A instance has no attribute 'a'
>>> a.a =3
>>> a.show()
3
Traceback (most recent call last):
File "<pyshell#212>", line 1, in <module>
a.show()
File "<pyshell#208>", line 4, in show
print self.__b
AttributeError: A instance has no attribute '_A__b'
>>> a.__b = 4
>>> a.show()
3
Traceback (most recent call last):
File "<pyshell#214>", line 1, in <module>
a.show()
File "<pyshell#208>", line 4, in show
print self.__b
AttributeError: A instance has no attribute '_A__b'
>>> a._A__b = 5
>>> a.show()
3
5
二.python3中的属性
在python3中属性得到了较为完整的实现,支持更加全面的保护机制。如果设置属性为只读,则无法修改其值,也无法为对象增加与属性同名的新成员,同时也无法删除对象的属性。
(1)只读,不可修改和删除
class A:
def __init__(self,v):
self.__v = v
@property
def v(self):
return self.__v
>>> a = A(3)
>>> a.v
3
>>> a.v = 4#只读属性不许修改
>>>
AttributeError: cannt set attribute
>>> a.vv = 5#动态增加形成员
>>> a.vv
5
>>> del a.vv#动态删除成员
>>> del a.v#试图删除对象失败
>>> a.v
3
#(2)下面可读,可修改,不可删除
class A:
def __init__(self,v):
self.__v = v
def __get(self):
return self.__v
def __set(self,v):
self.__v = v
v = property(__get,__set)
def show(self):
print self.__v
def show(self):
print self.__v
>>> a = A(3)
>>> a.v
3
>>> a.v = 4#允许修改
>>> a.v
4
>>> a.show()#属性值对应的私有变量也得到了修改
5
>>> del a.v#试图删除对象失败
#(3)下面可读,可修改,可删除
class A:
def __init__(self,v):
self.__v = v
def __get(self):
return self.__v
def __set(self,v):
self.__v = v
v = property(__get,__set,__del)
def show(self):
print self.__v
def show(self):
print self.__v