这次我们主要来聊聊跟对象的属性有关的魔术方法。
基础属性魔法方法
__getattr__魔术方法
__getattr__ 是 Python 中的一个特殊方法,用于在访问一个不存在的属性时被调用。如果一个对象定义了 __getattr__ 方法,那么当它的属性被访问时,如果该属性不存在,则 Python 会调用该对象的 __getattr__ 方法来处理这个访问。
以下是一个简单的示例,演示了如何使用 __getattr__ 方法:
class Example:
def __init__(self):
self.data = {
'a': 1, 'b': 2, 'c': 3}
def __getattr__(self, name):
if name in self.data:
return self.data[name]
else:
raise AttributeError(f"'{
type(self).__name__}' object has no attribute '{
name}'")
在这个示例中,我们定义了一个 Example 类,它有一个 data 属性,其中包含一些数据。在 __getattr__ 方法中,我们检查属性名称是否存在于 data 字典中。如果是,我们返回相应的值;否则,我们抛出一个 AttributeError 异常,表示该属性不存在。
现在,我们可以创建一个 Example 实例,并访问它的属性,即使这些属性并不存在:
>>> ex = Example()
>>> ex.a
1
>>> ex.b
2
>>> ex.c
3
>>> ex.d
AttributeError: 'Example' object has no attribute 'd'
在这个示例中,我们首先创建了一个 Example 实例,然后访问了它的属性 a、b 和 c,它们都存在于 data 字典中。然后我们试图访问属性 d,这个属性并不存在,于是 Python 调用了 __getattr__ 方法,并抛出了一个 AttributeError 异常。
需要注意的是,如果一个对象同时定义了 __getattr__ 和 __getattribute__ 方法,那么 __getattribute__ 方法会比 __getattr__ 方法更先被调用,因为它处理所有属性的访问,而不仅仅是不存在的属性。因此,如果您要使用 __getattr__ 方法,需要确保它只用于处理不存在的属性。
__getattribute__魔术方法
__getattribute__ 是 Python 中的一个特殊方法,用于在访问对象属性时被调用。当我们使用点号(.)或 getattr() 函数来访问一个对象的属性时,Python 会调用该对象的 __getattribute__ 方法来获取属性的值。与 __getattr__ 方法不同的是,__getattribute__ 方法对于对象的所有属性都会被调用,而不仅仅是不存在的属性。
以下是一个简单的示例,演示了如何使用 __getattribute__ 方法:
class Example:
def __init__(self):
self.data = {
'a': 1, 'b': 2, 'c': 3}
def __getattribute__(self, name):
try:
return object.__getattribute__(self, name)
except AttributeError:
if name in self.data:
return self.data[name]
else:
raise AttributeError(f"'{
type(self).__name__}' object has no attribute '{
name}'")
在这个示例中,我们定义了一个 Example 类,它有一个 data 属性,其中包含一些数据。在 __getattribute__ 方法中,我们首先尝试使用 object.__getattribute__ 方法来获取属性的值。如果该属性存在,则直接返回它的值。如果该属性不存在,则抛出一个 AttributeError 异常,表示该属性不存在。在这种情况下,我们检查属性名称是否存在于 data 字典中。如果是,我们返回相应的值;否则,我们抛出一个 AttributeError 异常。
现在,我们可以创建一个 Example 实例,并访问它的属性:
>>> ex = Example()
>>> ex.a
1
>>> ex.b
2
>>> ex.c
3
>>> ex.d
AttributeError: 'Example' object has no attribute 'd'
在这个示例中,我们首先创建了一个 Example 实例,然后访问了它的属性 a、b 和 c,它们都存在于 data 字典中。然后我们试图访问属性 d,这个属性并不存在,于是 Python 调用了 __getattribute__ 方法,并抛出了一个 AttributeError 异常。
需要注意的是,__getattribute__ 方法可能会导致无限递归的问题。因为它处理所有属性的访问,如果在 __getattribute__ 方法中又访问了其他属性,那么就会再次调用 __getattribute__ 方法,从而导致递归调用。为了避免这个问题,通常在 __getattribute__ 方法中使用 object.__getattribute__ 方法来获取属性的值。

最低0.47元/天 解锁文章
3402

被折叠的 条评论
为什么被折叠?



