__getattr__和__getattribute__有什么区别?

__getattr__ 和 __getattribute__ 都是 Python 中用于属性访问的特殊方法(魔术方法),但它们的使用场景和行为有所不同。以下是它们之间的主要区别:

###1. 调用时机- __getattribute__(self, name):

  • 当访问任何属性时都会被调用,不论该属性是否存在于对象的属性字典中。

  • 它是所有属性访问的基础,包括现有属性和不存在的属性。

  • __getattr__(self, name):
    -仅在尝试访问不存在的属性时才会被调用。

  • 如果访问的属性在对象的属性字典中存在,则不会触发 __getattr__

###2. 使用场景- __getattribute__:

  • 可以用于全局拦截对所有属性的访问,不管属性是否存在。
    -适合场景包括记录访问日志、实现代理等。

  • __getattr__:
    -适合用于提供默认行为或动态计算属性值,尤其在属性不存在时。

  • 常用于处理未定义的属性请求,比如实现懒加载、代理等。

###3. 示例以下是简单的示例来说明这两者的区别:


def __init__(self):  
  self.existing_attr = "I'm here!"  

def __getattribute__(self, name):  
  print(f"__getattribute__ called for {name}")  
  return super().__getattribute__(name) 
# 调用父类的方法 
def __getattr__(self, name):  
  print(f"__getattr__ called for {name}")  
  return f"{name} does not exist!" #处理不存在的属性obj = Example()  

#访问现有属性
print(obj.existing_attr) #触发 __getattribute__  

#访问不存在的属性
print(obj.non_existing_attr) 
#触发 __getattribute__,然后是 __getattr__  

输出:


rust

__getattribute__ called for existing_attrI'm here! __getattribute__ called for non_existing_attr__getattr__ called for non_existing_attrnon_existing_attr does not exist!

总结- __getattribute__ 是一个全面的拦截器,处理所有的属性访问,包括已存在和未存在的属性。

  • __getattr__ 是一个后备支持,当请求一个未定义的属性时调用。

理解这两者的差异可以帮助你更好地控制对象属性的访问和处理。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值