描述符

'''
1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用del删除属性时,触发
2.描述符是干什么的:描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中)
3.描述符分两种
一:数据描述符---至少实现了__get__()和__set__()
二:非数据描述符---没有实现__set__()
4.注意事项
一:描述符本身应该定义成新式类,被代理的类也应该是新式类
二:必须把描述符定义成这个类的类属性,不能为定义到构造函数中
三:要严格遵循该优先级,优先级由高到底分别是
a.类属性
b.数据描述符
c.实例属性
d.非数据描述符
e.找不到的属性触发__getattr__()
'''

# #描述符Str
# class Str:
#  def __get__(self, instance, owner):
#     print('Str调用')
#
#  def __set__(self, instance, value):
#     # self是name(Str实例化的对象),instance是p1,value是'alex'
#     print('Str设置...')
#
#  def __delete__(self, instance):
#     print('Str删除...')
#
# #描述符Int
# class Int:
#  def __get__(self, instance, owner):
#     print('Int调用')
#
#  def __set__(self, instance, value):
#     print('Int设置...')
#
#  def __delete__(self, instance):
#     print('Int删除...')
#
# class People:
#  name = Str()
#  age = Int()
#  def __init__(self, name, age): #name被Str类代理,age被Int类代理,
#     self.name = name
#     self.age = age
#
# #何地?:定义成另外一个类的类属性
#
# #何时?:且看下列演示
#
# p1 = People('alex', 18)
# print(p1.__dict__)
# print(People.__dict__) # 'name': <__main__.Str object at 0x000001EA4C7D3D30>, 'age': <__main__.Int object at 0x000001EA4C840190>
#
# #描述符Str的使用
# p1.name
# p1.name = 'egon'
# del p1.name
#
# #描述符Int的使用
# p1.age
# p1.age = 18
# del p1.age
#
# #我们来瞅瞅到底发生了什么
# print(p1.__dict__)
# print(People.__dict__)
#
# #补充
# print(type(p1) == People) #type(obj)其实是查看obj是由哪个类实例化来的
# print(type(p1).__dict__ == People.__dict__)


'''类属性>数据描述符'''
# class Foo:
#  def __set__(self, instance, value):
#     print('---set')
#
#  def __get__(self, instance, owner):
#     print('---get')
#
#  def __delete__(self, instance):
#     print('---delete')
#
# class Bar:
#  x = Foo()
#
#  def __getattr__(self, item):
#     return '找不到此属性%s' % item
#
# print(Bar.x) # ---get None(__get__方法没有返回值)
#
# Bar.x = 1 # 不会触发__set__
# print(Bar.x) # 1
#
# del Bar.x # 不会触发__delete__
# print(Bar.__dict__) # 属性x已经被删除


'''数据描述符>实例属性(类属性和实例属性同名)'''
# class Foo_1:
#  def __set__(self, instance, value):
#     print('---set')
#
#  def __get__(self, instance, owner):
#     print('---get')
#
#  def __delete__(self, instance):
#     print('---delete')
#
# class Car:
#  name = Foo_1()
#  def __init__(self, name):
#     self.name = name
#
# c1 = Car('bmw') # ---set 初始化设置值
# print(c1.__dict__) # {} 实例属性字典为空
# print(c1.name) # ---get None 获取值
# del c1.name # ---delete 删除
# c1.name = 'audi' # ---set
# print(c1.__dict__) # {}


'''实例属性>非数据描述符'''
# class Foo_2:
#  def __get__(self, instance, owner):
#     print('---get')
#
# class Func:
#  name = Foo_2()
#  def __init__(self, name):
#     self.name = name
#
# ff = Func('alex')
# print(ff.__dict__) # {'name': 'alex'}
# print(ff.name) # 'alex'


'''非数据描述符>__getattr__'''
# class Foo_3:
#  def __get__(self, instance, owner):
#     print('---get')
#
# class Func_1:
#  name = Foo_3()
#  def __init__(self, name):
#     self.name = name
#
#  def __getattr__(self, item):
#     print('找不到此属性')
#
# aa = Func_1('wupeiqi')
# print(aa.name)
# aa.age # 找不到此属性
while True: print('studying...')
原文地址:https://www.cnblogs.com/xuewei95/p/14722986.html