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'

