属性描述符

__getattr__

from datetime import date


class User:
    def __init__(self, name, birthday):
        self.name = name
        self.birthday = birthday


if __name__ == '__main__':
    u = User('shell', date(year=1996, month=1, day=1))
    print(u.birthday)
    print(u.age)
    

显然我们访问age属性会报错因为没有age属性,实际上是先访问__getattr__魔法方法

from datetime import date


class User:
    def __init__(self, name, birthday):
        self.name = name
        self.birthday = birthday

    def __getattr__(self, item):
        print(item)


if __name__ == '__main__':
    u = User('shell', date(year=1996, month=1, day=1))
    print(u.birthday)
    print(u.age)
    print(u.hight)
    
1996-01-01
age
None
hight
None

__getattr__方法会获取不存在的属性名(age,hight)并保存在item中。

注意打印一个没有返回值的函数结果都是None,所以会有两个None

getattaribute

__getattaribute__是属性访问拦截器,当这个累的属性被实例访问时,会自动调用类的__getattaribute__方法。注意,不要轻易的重写__getattaribute__方法。

参考:https://blog.csdn.net/qq_26442553/article/details/82467777

属性描述符

  • __get__
  • __set__
  • __del__

实现上述中任意一个魔法方法即可称为属性描述符,若只实现__get__称为非数据属性描述符,若同时实现__get__,__set__称为数据属性描述符。

class IntField:
    def __get__(self, instance, owner):
        print(instance)
        print(owner)
        print('__get__')

    def __set__(self, instance, value):
        print(instance)
        print(value)
        print('__set__')


class User:
    age = IntField()


u = User()
u.age = 30
print(u.age)

<__main__.User object at 0x00000218759585F8>
30
__set__
<__main__.User object at 0x00000218759585F8>
<class '__main__.User'>
__get__
None

传入30后,先调用age对象的__set__,打印后调用__get__。instance都是User对象的内存地址,value是传入的值,owner是User类。

class IntField:
    # 数据描述符
    def __get__(self, instance, owner):
        return self.values

    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise TypeError('类型错误')
        self.values = value


# class NonDataIntField:
#     # 非属性描述符
#     def __get__(self, instance, owner):
#         return self.value


class User:
    age = IntField()


u = User()
u.age = 30
print(u.age)

参考文章:https://www.cnblogs.com/xyz2b/p/10529068.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值