十四、python 访问属性和属性装饰器
访问属性:
1、直接访问(上一讲得直接操作)
2、通过自定义get() 、 set()方法来访问
3、通过属性装饰器
@property 读
@***.setter 写
@***.deleter 删除
4、通过属性符访问
代码重用
描述符属性必须定义为类属性
-----------------------------------------------------------
#属性访问
class Chinese(object):
nation = 'Chain'
def __init__(self, id, name):
self._id = id
self.__name = name
self.__mail = None
def sayHi(self, msg):
print self.__name,msg
#自定义get 、 set 方法访问
def getId(self):
return self._id
def setId(self, id):
self._id = id
# 定义属性装饰器
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
@name.deleter
def name(self):
del self.__name
#定义实例
aidon = Chinese(1,'aidon')
print aidon.getId()
aidon.setId(10)
print aidon.getId()
print aidon.name
aidon.name = 'bajie'
print aidon.name
del aidon.name #删除
#print aidon.name
print aidon._Chinese__mail
print aidon.__dict__
--------------------------------------------------------------
---------------------------------------------------------------
#类描述符定义
class Property(object):
def __init__(self, propname, datatype, default=None):
self._name = '_'+propname+'_'
self._type = datatype
self._default = default if default else self._type()
def __get__(self, instance, owner):
return getattr(instance,self._name,self._default)
def __set__(self, instance, value):
if not isinstance(value,self._type):
raise TypeError('Type Error,must be %s type0' % self._type)
setattr(instance,self._name,value)
def __del__(self):
pass
class Email(Property):
def __init__(self,propname,default=None):
super(Email,self).__init__(propname,str,default)
def __set__(self, instance, value):
if not isinstance(value,self._type):
raise TypeError('Type Error,must be %s type0' % self._type)
if not '@' in value:
raise ValueError('Email address is not valid')
setattr(instance,self._name,value)
class Chinese(object):
Id = Property('id', int) #描述符必须是类属性,Id随便定义,和后面没有任何关系,它相当于对外访问提供的一个接口
Name = Property('name', str)
Email = Email('email')
#注意:类的成员方法中,也必须使用类的描述符
def __init__(self,id,name,email):
self.Id = id
self.Name = name
self.Email = email
#---------使用交互式测试--------------------
aidon = Chinese()
aidon.__dict__
aidon.Id #此时都是默认类型的默认值才对
aidon.Name
aidon.Email
#赋值
aidon.Id= 100
aidon.Name = 'aidon'
aidon.Email = '[email protected]'
aidon.Id
aidon.__dict__
#设置和类型不匹配的值
aidon.Name = 123123
aidon.Email = 'abc'
#测试类的成员方法
bajie = Chinese(1,'bajie','[email protected]')
bajie.Name
bajie.__dict__
-----------------------------------------------------------------