python对象的魔法方法(一) - __getattr__ vs __getattribute__
发布人:shili8
发布时间:2025-01-15 12:13
阅读次数:0
**Python 对象的魔法方法 (一) - `__getattr__` vs `__getattribute__`**
在 Python 中,对象的属性访问是通过魔法方法来实现的。这些魔法方法允许我们自定义对象的行为,使得它能够像普通类型一样使用。其中两个最重要的魔法方法是 `__getattr__` 和 `__getattribute__`。虽然它们看起来很相似,但它们有着不同的用途和实现方式。
**1. `__getattr__`**
`__getattr__` 是一个用于获取属性值的魔法方法。当我们尝试访问一个对象的属性时,Python 会先检查这个属性是否存在。如果不存在,它就会调用 `__getattr__` 方法来获取该属性的值。这个方法接受两个参数:第一个是属性名,第二个是当前对象。
class MyClass: def __getattr__(self, name): if name == 'foo': return 'bar' else: raise AttributeError(f"'MyClass' object has no attribute '{name}'") obj = MyClass() print(obj.foo) # 输出: bartry: print(obj.baz) except AttributeError as e: print(e) # 输出: 'MyClass' object has no attribute 'baz'
在这个例子中,我们定义了一个 `MyClass` 类,它有一个 `__getattr__` 方法。如果属性名是 `'foo'`,它就会返回 `'bar'`。否则,它会抛出一个 `AttributeError` 异常。
**2. `__getattribute__`**
`__getattribute__` 是用于获取任意属性值的魔法方法。当我们尝试访问一个对象的属性时,Python 会首先调用这个方法来获取该属性的值。这个方法接受两个参数:第一个是属性名,第二个是当前对象。
class MyClass: def __getattribute__(self, name): if name == 'foo': return 'bar' else: raise AttributeError(f"'MyClass' object has no attribute '{name}'") obj = MyClass() print(obj.foo) # 输出: bartry: print(obj.baz) except AttributeError as e: print(e) # 输出: 'MyClass' object has no attribute 'baz'
这个例子与上一个例子非常相似。唯一的区别是,我们使用了 `__getattribute__` 方法来获取属性值。
**3. 区别**
虽然 `__getattr__` 和 `__getattribute__` 都用于获取属性值,但它们有着不同的用途和实现方式。
* `__getattr__` 只会被调用当我们尝试访问一个对象的属性时,如果该属性不存在。
* `__getattribute__` 会在任何情况下都被调用,包括当我们尝试访问一个对象的属性时,如果该属性存在或不存在。
**4. 总结**
在本文中,我们讨论了 Python 对象的魔法方法 `__getattr__` 和 `__getattribute__`。虽然它们看起来很相似,但它们有着不同的用途和实现方式。`__getattr__` 只会被调用当我们尝试访问一个对象的属性时,如果该属性不存在,而 `__getattribute__` 会在任何情况下都被调用,包括当我们尝试访问一个对象的属性时,如果该属性存在或不存在。
**5. 参考**
* [Python 文档 - `__getattr__`]( />* [Python 文档 - `__getattribute__`]( />
**6. 示例代码**
class MyClass: def __init__(self): self.foo = 'bar' def __getattr__(self, name): if name == 'baz': return 'qux' else: raise AttributeError(f"'MyClass' object has no attribute '{name}'") obj = MyClass() print(obj.foo) # 输出: bartry: print(obj.baz) except AttributeError as e: print(e) # 输出: 'MyClass' object has no attribute 'baz' class MyOtherClass: def __init__(self): self.qux = 'quux' def __getattribute__(self, name): if name == 'corge': return 'grault' else: raise AttributeError(f"'MyOtherClass' object has no attribute '{name}'") obj2 = MyOtherClass() print(obj2.qux) # 输出: quuxtry: print(obj2.corge) except AttributeError as e: print(e) # 输出: 'MyOtherClass' object has no attribute 'corge'