十八.描述符(__get__,__set__,__delete__)

Posted sup-to

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十八.描述符(__get__,__set__,__delete__)相关的知识,希望对你有一定的参考价值。

描述符(__get__,__set__,__delete__)

 

4 注意事项:
一 描述符本身应该定义成新式类,被代理的类也应该是新式类
二 必须把描述符定义成这个类的类属性,不能为定义到构造函数中
三 要严格遵循该优先级,优先级由高到底分别是
1.类属性
2.数据描述符
3.实例属性
4.非数据描述符
5.找不到的属性触发__getattr__()

 

1 描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用del删除属性时,触发
class Foo: #在python3中Foo是新式类,它实现了三种方法,这个类就被称作一个描述符
    def __get__(self, instance, owner):
        pass
    def __set__(self, instance, value):
        pass
    def __delete__(self, instance):
        pass

定义一个描述符
2 描述符是干什么的:描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中)

class Foo:
    def __get__(self, instance, owner):
        print(触发get)
    def __set__(self, instance, value):
        print(触发set)
    def __delete__(self, instance):
        print(触发delete)

#包含这三个方法的新式类称为描述符,由这个类产生的实例进行属性的调用/赋值/删除,并不会触发这三个方法
f1=Foo()
f1.name=egon
f1.name
del f1.name
#疑问:何时,何地,会触发这
#描述符Str
class Str:
    def __get__(self, instance, owner):
        print(Str调用)
    def __set__(self, instance, value):
        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)

#描述符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__)
# 描述符应用之何时?何地?三个方法的执行\
# 执行顺序
# Str设置...
# Int设置...
# Str调用
# Str设置...
# Str删除...
# Int调用
# Int设置...
# Int删除...
# 
# ‘__module__‘: ‘__main__‘, ‘name‘: <__main__.Str object at 0x00000177DAFD5048>, ‘age‘: <__main__.Int object at 0x00000177DAFD5080>, ‘__init__‘: <function People.__init__ at 0x00000177DAFCAEA0>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘People‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘People‘ objects>, ‘__doc__‘: None
# True
# True

二 .描述符分两种

  1.  数据描述符:至少实现了__get__()和__set__()

一 数据描述符:至少实现了__get__()和__set__()

1 class Foo:
2     def __set__(self, instance, value):
3         print(set)
4     def __get__(self, instance, owner):
5         print(get)


# 实例属性是低于 数据描述符   所以优先找的是描述符属性   优先级

class Foo:
def __set__(self, instance, value):
print(‘set‘)
print(value)
def __get__(self, instance, owner):
print(‘get‘)
print(owner)
class Per(object):
name=Foo()
def __init__(self,name):
self.name=name
def aa(self):
print(self.name)

f=Per("李四")
f.name
f.aa()
#
# get
# <class ‘__main__.Per‘>
# get
# <class ‘__main__.Per‘>
# None




 

2. 非数据描述符:没有实现__set__()

1 class Foo:
2     def __get__(self, instance, owner):
3         print(get)



# 实例属性是高于 非数据描述符   所以优先找的是实例属性    这就是优先级
class Foo:
def __get__(self, instance, owner):
print(‘get‘)
class Per(object):
name=Foo()
def __init__(self,name):
self.name=name
def aa(self):
print(self.name)
f=Per("李四")
print(f.name)
print(f.__dict__)
print(Per.__dict__)

# 李四
# ‘name‘: ‘李四‘
# ‘__module__‘: ‘__main__‘, ‘name‘: <__main__.Foo object at 0x00000268526C8860>, ‘__init__‘: <function Per.__init__ at 0x00000268526CABF8>, ‘aa‘: <function Per.aa at 0x00000268526CAD08>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Per‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Per‘ objects>, ‘__doc__‘: None

 

以上是关于十八.描述符(__get__,__set__,__delete__)的主要内容,如果未能解决你的问题,请参考以下文章

描述符__get__(),__set__(),__delete__()(三十七)

Python进阶-----描述符(__get__(),__set__(),__delete__())

描述符get/set/delete,init/new/call,元类

了解 __get__ 和 __set__ 以及 Python 描述符

描述符(__get__,__set__,__delete__)

描述符