39.Python进阶_魔法方法___getattribute__和__getattr__

  • 使用___getattribute__获取不存在的属性会报异常,
  • __getattr__会捕获异常
class Hero():
    def __init__(self,name):
        self.name = name

    def __setattr__(self, key, value):
        '''给设置属性时,会调用此方法'''
        if key == 'name':
            value = '888'
        print('---__setattr__--')
        object.__setattr__(self, key, value)
    def __getattribute__(self, item):
        '''查找属性时,会直接调用该方法,进行查找'''
        print(f'这个是__getattribute__:item:{item}')
        return object.__getattribute__(self,item)

h = Hero('静静')
print(h.name)
print(h.age)


运行结果:

---__setattr__--
Traceback (most recent call last):
这个是__getattribute__:item:name
888
这个是__getattribute__:item:age
  File "C:/workspace/pythonTest/pythonDemo/getattr.py", line 25, in <module>
    print(h.age)
  File "C:/workspace/pythonTest/pythonDemo/getattr.py", line 16, in __getattribute__
    return object.__getattribute__(self,item)
AttributeError: 'Hero' object has no attribute 'age'

由运行结果可知由于age属性并不存在,所以此刻会会报出异常:

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

    def __setattr__(self, key, value):
        '''给设置属性时,会调用此方法'''
        '''当这个类的属性被访问时,会自动调用类的__getattribute__方法'''

        if key == 'name':
            value = '888'
        print('---__setattr__--')
        object.__setattr__(self, key, value)
    def __getattribute__(self, item):
        '''查找属性时,会直接调用该方法,进行查找'''
        print(f'这个是__getattribute__:item:{item}')
        return object.__getattribute__(self,item)
    def __getattr__(self, item):
        '属性不存在,该方法会主动捕获异常'
        print(f'这个是__getattr__:item:{item}')



h = Hero('静静')
print(h.name)
print(h.age)

运行结果:

---__setattr__--
这个是__getattribute__:item:name
888
这个是__getattribute__:item:age
这个是__getattr__:item:age
None

由运行结果可知,获取属性会先去调用__getattribute__方法,发现不存在然后再去调用 __getattr__方法;

使用 __getattr__当属性不存在时可以捕获并抛出异常:
class Hero():
    def __init__(self,name):
        self.name = name

    def __setattr__(self, key, value):
        '''给设置属性时,会调用此方法'''
        if key == 'name':
            value = '888'
        print('---__setattr__--')
        object.__setattr__(self, key, value)
    def __getattribute__(self, item):
        '''查找属性时,会直接调用该方法,进行查找'''
        print(f'这个是__getattribute__:item:{item}')
        return object.__getattribute__(self,item)
    def __getattr__(self, item):
        '属性不存在,该方法会主动捕获异常'
        print(f'这个是__getattr__:item:{item}')
        if item == 'age':
            return 111
        raise AttributeError

        return object.__getattr__(self, item)

    def __delattr__(self, item):
        print(f'这个是item:{item}')
        if item == 'name':
            pass
        else:
            object.__delattr__(self,item)


h = Hero('静静')
print(h.age)
---__setattr__--
这个是__getattribute__:item:age
这个是__getattr__:item:age
111

`__getattr__`和`__getattribute__`是Python中特殊的方法,用于处理对象的属性访问和获取。 `__getattr__`用于在对象实例的属性不存在时被调用,通常在动态获取属性的情况下使用。当我们尝试访问一个对象上不存在的属性时,Python解释器会自动调用`__getattr__`方法。我们可以在这个方法中定义对不存在属性的处理逻辑,比如返回默认值或者触发异常。 下面是一个示例: ``` class MyClass: def __getattr__(self, name): return f"Attribute {name} does not exist." obj = MyClass() print(obj.some_attr) # Output: Attribute some_attr does not exist. ``` `__getattribute__`用于在对象实例的属性被访问时被调用。与`__getattr__`不同,`__getattribute__`会在所有属性访问上被调用,无论属性是否存在。我们可以通过在`__getattribute__`方法中自定义属性访问的行为,比如在访问属性前执行一些操作或返回特定的值。 下面是一个示例: ``` class MyClass: def __getattribute__(self, name): print(f"Accessing attribute {name}") return super().__getattribute__(name) obj = MyClass() print(obj.some_attr) # Output: # Accessing attribute some_attr # None ``` 注意,使用`__getattribute__`时需要谨慎,因为在方法内部访问同个实例的其他属性时可能会触发无限递归调用。在这种情况下,可以通过使用`super()`来避免无限递归。 综上所述,`__getattr__`和`__getattribute__`是Python中用于处理对象属性访问和获取的特殊方法,分别用于处理不存在属性和所有属性的访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值