Python学海无涯路【第38回】:类的内置attr属性


1、__getattr__

  • 调用不存在的属性时,会调用此函数
class Animal:
    a=1
    def __init__(self,name):
        self.name=name
    def __getattr__(self, item):
        print("你找的【%s】属性不存在"%item)
if __name__ == '__main__':
    animal=Animal("佩奇")
    animal.aaa		#调用不存在的属性才会执行__getattr__

输出:
你找的【aaa】属性不存在

2、__delattr__

2.1、__delattr__的触发

  • 执行删除操作时会触发此函数
class Animal:
    a=1
    def __init__(self,name):
        self.name=name

    def __delattr__(self, item):
        print("删除操作__delattr__")
        #del self.item			#无限递归
        self.__dict__.pop(item)
if __name__ == '__main__':
    animal=Animal("佩奇")
    del animal.a

2.2、__delattr__的作用

  • 系统有个默认的__delattr__
  • 如果类中定义了__delattr__主法,系统默认的将失效
  • __delattr__方法被重写,需要自己写设置属性的方法,如果不写,值将无法删除。
  • 可以用 self.__dict__.pop(item)
  • 不能用del self.item ,否则会无限递归
class Animal:
    name = "待初始化"

    def __init__(self, name):
        self.name = name

    def __delattr__(self, item):
        pass


if __name__ == '__main__':
    animal = Animal("佩奇")
    print(animal.__dict__)
    print(animal.name)
    del animal.name
    print(animal.__dict__)
    print(animal.name)

2.3、__delattr__的用法示例

不允许删除任何属性

class Animal:
    name = "待初始化"

    def __init__(self, name):
        self.name = name

    def __delattr__(self, item):
        print("【%s】属性不允许删除"%item)


if __name__ == '__main__':
    animal = Animal("佩奇")
    print(animal.__dict__)
    print(animal.name)
    del animal.name
    print(animal.__dict__)
    print(animal.name)

输出:
{‘name’: ‘佩奇’}
佩奇
【name】属性不允许删除
{‘name’: ‘佩奇’}
佩奇

3、__setattr__

3.1、__setattr__的触发

  • 为类的属性赋值时会触发
class Animal:
    a = 1

    def __init__(self, name):
        self.name = name

    def __setattr__(self, key, value):
        print("执行__setattr__")
        #self.key=value #这样写会无限递归
        self.__dict__[key]=value

if __name__ == '__main__':
    animal = Animal("佩奇")
    print(animal.__dict__)
    animal.a=2
    print(animal.__dict__)

3.2、__setattr__的作用

  • 系统有个默认的__setattr__

  • 如果类中定义了__setattr__主法,系统默认的将失效

  • __setattr__方法被重写,需要自己写设置属性的方法,如果不写,值将无法传入,本例中“佩奇”就无法传给name。

  • 可以用self.__dict__[key]=value

  • 不能用self.key=value,否则会无限递归

class Animal:
    name="待初始化"
    def __init__(self, name):
        self.name = name

    def __setattr__(self, key, value):
        print("执行__setattr__")
        #self.key=value
        #self.__dict__[key]=value

if __name__ == '__main__':
    animal = Animal("佩奇")
    print(animal.__dict__)
    print(animal.name)

输出:
执行__setattr__
{}
待初始化

3.2、__setattr__用法示例

实例化Animal时name只能传字符串

class Animal:
    name = "待初始化"

    def __init__(self, name):
        self.name = name

    def __setattr__(self, key, value):
        if (key=="name" and type(value) is str):
            self.__dict__[key]=value
        else:
            print("【%s】不是字符串,无法赋值给【%s】"%(value,key))


if __name__ == '__main__':
    animal = Animal("佩奇")
    print(animal.__dict__)
    print(animal.name)
    animal = Animal(1)
    print(animal.__dict__)
    print(animal.name)

输出:
{‘name’: ‘佩奇’}
佩奇
【1】不是字符串,无法赋值给【name】
{}
待初始化

4、__getattribute__

4.1、__getattribute__触发的条件

  • 实例对象调用存在的属性会触发
  • 实例对象调用不存在的属性会触发
  • __getattr__就没有了触发的机会
class Animal:
    def __init__(self,name):
        self.name=name

    def __getattr__(self, item):
        print("执行了__getattr__")

    def __getattribute__(self, item):
        print("执行了___getattribute__")

if __name__ == '__main__':
    animal=Animal("佩奇")
    animal.name     #属性存在
    animal.aaaa     #属性不存在

输出:
执行了___getattribute__
执行了___getattribute__

4.2、AttributeError异常时会继续调用__getattr__

  • __getattribute__抛出AttributeError异常时,会继续调用__getattr__
  • 其他异常不会
class Animal:
    def __init__(self,name):
        self.name=name

    def __getattr__(self, item):
        print("执行了__getattr__")

    def __getattribute__(self, item):
        print("执行了___getattribute__")
        raise AttributeError("抛出了AttributeError异常")

if __name__ == '__main__':
    animal=Animal("佩奇")
    animal.name     #属性存在
    animal.aaaa     #属性不存在

输出:
执行了___getattribute__
执行了__getattr__
执行了___getattribute__
执行了__getattr__

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值