python对象的魔法方法(一) - __getattr__ vs __getattribute__

了解python的都知道,python对象有很多魔法方法或者叫特殊方法,他们往往以双下划线和单词组成,比如今天的两位 __getattribute____getattr__

这俩方法乍一看,嘿,还挺像,一个单词长一些,一个单词短一些,虽然都是控制属性的访问方法,但是他们之间是有差别的。

__getattribute__

Called unconditionally to implement attribute accesses for instances of the class. If the class also defines getattr(), the latter will not be called unless getattribute() either calls it explicitly or raises an AttributeError. This method should return the (computed) attribute value or raise an AttributeError exception.

意思就是 __getattribute__ 会无条件的实现对类实例的属性控制。在同时存在 __getattr__ 时候, __getattr__ 并不会被访问到,除非你明确的在 __getattribute__ 里面调用了它。

__getattr__

Called when the default attribute access fails with an AttributeError (either getattribute() raises an AttributeError because name is not an instance attribute or an attribute in the class tree for self; or get() of a name property raises AttributeError). This method should either return the (computed) attribute value or raise an AttributeError exception.

__getattr__ 呢则是在默认属性失败的情况下,会去调用它,看看它是否有实现对属性的访问权。在这里要注意一点就是: Note that if the attribute is found through the normal mechanism, __getattr__() is not called. - 在常规机制下能访问到的属性,getattr() 是不会被调用的。

具体看以下例子:

class MyClass(object):

    def __init__(self):
        self.name = "John Doe"

    def __getattribute__(self, name):
    	print(f"__getattribute__: {name}")
        if name == "age":
            return 30
        else:
            return object.__getattribute__(self, name)

    def __getattr__(self, name):
        print("The attribute {} is not defined".format(name))


instance = MyClass()

print(instance.name)  # John Doe
print(instance.age)  # 30
print(instance.address)  # The attribute address is not defined

"""
Output:
__getattribute__: name
John Doe

__getattribute__: age
30

__getattribute__: address
The attribute address is not defined
"""

从这个例子可以看到:

  1. 属性的访问,都会直接走 __getattribute__ 方法
  2. 常规属性的访问,并不会直接走 __getattr__ 方法
  3. 当对象访问不存在的属性名字时候,__getattr__ 会被调用;
  4. 【可以自己将 __getattr__ 注释掉】如果没有该魔法方法,则会报错 AttributeError: 'MyClass' object has no attribute 'address'
__getattribute__是Python中的一个特殊方法,用于在访问对象属性时进行自定义操作。当在类内定义了__getattribute__方法时,它会打破原有的属性查找方式。在使用obj.value查找属性时,会无条件调用__getattribute__方法。\[1\] 下面是一个使用__getattribute__方法的示例: ```python class MyClass: def __getattribute__(self, item): print('__getattribute__') return super().__getattribute__(item) if __name__ == '__main__': obj = MyClass() obj.value ``` 在上述示例中,当访问obj.value时,会触发__getattribute__方法,并打印出'__getattribute__'。然后,super().__getattribute__(item)会调用父类的__getattribute__方法来获取属性值。\[2\] 需要注意的是,__getattribute__方法在属性查找时会被优先调用,而不管属性是否存在。如果属性不存在,会引发AttributeError异常。如果想在属性不存在时执行自定义操作,可以使用__getattr__方法。\[3\] #### 引用[.reference_title] - *1* [python魔法方法 _getattr_ 和 __getattribute__](https://blog.csdn.net/weixin_29864813/article/details/112992737)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Python的__getattr__和__getattribute__](https://blog.csdn.net/weixin_39812046/article/details/110703391)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值