这次我们主要来聊聊跟对象的属性有关的魔术方法。
基础属性魔法方法
__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__
方法来