__getattr__与__getattribute__魔术方法
时间: 2023-07-21 13:35:40 浏览: 116
浅谈 Python 魔法函数 __getattr__ 与 __getattribute__
`__getattr__` 和 `__getattribute__` 都是 Python 中的魔术方法,用于在类中处理属性的访问。两者有一些区别:
- `__getattr__` 方法在访问一个不存在的属性时被调用。如果实现了 `__getattr__` 方法,那么在访问一个不存在的属性时,Python 解释器会自动调用该方法并将属性名作为参数传递给它。该方法应该返回一个值来代替访问的属性。如果该方法无法提供属性的值,那么 Python 解释器会引发 `AttributeError` 异常。
- `__getattribute__` 方法在访问一个属性时被调用。该方法在访问任何属性时都会被调用,而不仅仅是不存在的属性。如果实现了 `__getattribute__` 方法,那么在访问属性时,Python 解释器会自动调用该方法并将属性名作为参数传递给它。该方法应该返回属性的值。如果该方法无法提供属性的值,那么 Python 解释器会引发 `AttributeError` 异常。
下面是一个简单的例子,演示了 `__getattr__` 和 `__getattribute__` 方法的用法:
```python
class MyClass:
def __init__(self):
self.data = {}
def __getattr__(self, name):
if name in self.data:
return self.data[name]
else:
raise AttributeError(f"'MyClass' object has no attribute '{name}'")
def __getattribute__(self, name):
if name == 'data':
return object.__getattribute__(self, 'data')
elif name in self.data:
return self.data[name]
else:
raise AttributeError(f"'MyClass' object has no attribute '{name}'")
```
在上述代码中,我们定义了一个名为 `MyClass` 的类,该类包含一个字典属性 `data`。我们分别实现了 `__getattr__` 和 `__getattribute__` 方法。在 `__getattr__` 方法中,我们检查所访问的属性是否存在于字典中。如果是,我们返回字典中的值;否则,我们引发一个 `AttributeError` 异常。在 `__getattribute__` 方法中,我们首先检查所访问的属性是否为 `data`。如果是,我们返回对象的 `data` 属性。否则,我们检查所访问的属性是否存在于字典中。如果是,我们返回字典中的值;否则,我们引发一个 `AttributeError` 异常。
下面是如何使用 `MyClass` 类:
```python
my_obj = MyClass()
my_obj.data['a'] = 1
my_obj.data['b'] = 2
print(my_obj.a) # 1
print(my_obj.b) # 2
print(my_obj.c) # AttributeError: 'MyClass' object has no attribute 'c'
```
在上述示例中,我们创建了一个 `MyClass` 对象,并使用 `__getattr__` 和 `__getattribute__` 方法来访问对象的属性。我们首先向对象的 `data` 字典中添加两个键值对。然后,我们尝试访问这些键值对,以及不存在的键值对。在访问存在的键值对时,`__getattr__` 和 `__getattribute__` 方法都会返回正确的值。在访问不存在的键值对时,`__getattr__` 方法会引发 `AttributeError` 异常,而 `__getattribute__` 方法会引发一个相同的异常。
阅读全文