• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
ellaha
博客园    首页    新随笔    联系   管理    订阅  订阅
__getattr__与__getattribute__的区别

https://docs.python.org/zh-cn/3/reference/datamodel.html#customizing-attribute-access

__getattr__

__getattribute__

__setattr__
__getattr__与__getattribute__均是一般实例属性截取函数(generic instance attribute interception method),其中,__getattr__可以用在python的所有版本中,
而__getattribute__只可以用到新类型类中(New-style class),其主要的区别是__getattr__只截取类中未定义的属性,而__getattribute__可以截取所有属性

实例instance通过instance.name访问属性name,只有当属性name没有在实例的__dict__或它构造类的__dict__或基类的__dict__中没有找到,才会调用__getattr__。
当属性name可以通过正常机制追溯到时,__getattr__是不会被调用的。如果在__getattr__(self, attr)存在通过self.attr访问属性,会出现无限递归错误。

object.__getattribute__(self, name) 实例`instance`通过`instance.name`访问属性`name`,`__getattribute__`方法一直会被调用,无论属性`name`是否追溯到。
如果类还定义了`__getattr__`方法,除非通过`__getattribute__`显式的调用它,或者`__getattribute__`方法出现`AttributeError`错误,否则`__getattr__`方法不会被调用了。
如果在`__getattribute__(self, attr)`方法下存在通过`self.attr`访问属性,会出现无限递归错误。

class Test:
    def __getattr__(self, item):
        # 当我们访问属性的时候,如果属性不存在(出现AttrError),该方法会被触发
        print('调用__getattr__方法')
        # object.__getattribute__(self, item)
        # return 100

    def __getattribute__(self, item):
        # 查找属性的时候第一时间触发该方法找属性
        print('调用__getattribute__方法')
        # return 100
        # return super().__getattribute__(item)

    def __setattr__(self, key, value):
        # 这个方法在给对象设置属性的时候触发
        print('调用__setattr__方法')
        # print(key, value)


    def __delattr__(self, item):
        # 这个方法在删除属性的时候会被触发
        print('调用__delattr__方法')

        if item == 'age':
            pass
        else:
            super().__delattr__(item)

t = Test()
t.name = 'hh'
print(t.name)

 

__delattr__
posted on 2021-01-03 11:15  ellaha  阅读(108)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3