python的数据描述符
描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用del删除属性时,触发
1.描述符的应用
判断实例化对象时所传参数的类型是否正确
class Typed(object):
def __init__(self,key,key_type):
self.key=key
self.key_type=key_type
def __get__(self, instance, owner):
print('------',self)
def __set__(self, instance, value):
if not isinstance(value,self.key_type):
print(self.key_type)
raise AttributeError('传入类型不对,应该传入类型为 ' %self.key_type)
instance.__dict__[self.key]=value
def __delete__(self, instance):
print('delete')
class school(object):
name=Typed('name',str)
adr=Typed('addr',str)
def __init__(self,name,adr):
self.name=name
self.adr=adr
def zhao(self):
print('{}可以招1000人'.format(self.name))
name='beida'.encode('utf-8')
addr='beij'.encode('utf-8')
s1=school(name,addr)
print(s1.__dict__)
#{u'name': 'beida', u'addr': 'beij'}
数据描述符,对象访问顺序 依次向下
类属性
数据描述符: __get__ __set__
实例属性
非数据描述符: 没有 __set__
找不到属性触发 __getattr__
2.自实现装饰器property
class zizhiproperty(object):
def __init__(self,key):
self.key=key
def __get__(self, instance, owner):
print('get')
print(instance,owner)
return self.key(instance)
class school(object):
def __init__(self,name,adr):
self.name=name
self.adr=adr
@zizhiproperty##zhao=zizhiproperty(zhao)
def zhao(self):
print('{}可以招1000人'.format(self.name))
return self.name
def __getattr__(self, item):
print('没有这个属性')
s1=school('liu','beijing')
print(s1.zhao)
#############
get
(<__main__.school object at 0x0000000003B9C518>, <class '__main__.school'>)
liu可以招1000人
liu
3.自定义装饰器classmethod
class zizhiclassmethod(object):
def __init__(self,key):
self.key=key
def __get__(self, instance, owner):
def wrapper(*args,**kwargs):
return self.key(owner)
return wrapper
class school(object):
history='悠久'
def __init__(self,name,adr):
self.name=name
self.adr=adr
def zhao(self):
print('{}可以招1000人'.format(self.name))
return self.name
@zizhiclassmethod ##run=classmethod(run)
def run(cls):
return cls.history
def __getattr__(self, item):
print('没有这个属性')
s1=school('liu','beijing')
print(s1.__dict__)
print(s1.run())
print(school.run())
#####################
{'adr': u'beijing', 'name': u'liu'}
悠久
悠久