Python 中的 __getattr__ 方法詳解

1. __getattr__ 的作用

__getattr__ 是 Python 的一個魔術方法(Magic Method)。當嘗試訪問一個對象的屬性,而該屬性不存在時,Python 會自動調用此方法。它允許你自定義對不存在屬性的行為。

定義形式:

def __getattr__(self, name: str):
    # name 是被訪問的屬性名稱(字符串形式)
    ...

2. 工作原理

當對象的屬性查找失敗時(即該屬性不存在時),Python 會調用 __getattr__ 方法來處理。這通常用於動態生成屬性或提供默認行為。

屬性查找順序:

  1. Python 首先在對象的 __dict__ 中查找屬性。
  2. 如果該屬性不存在,會檢查是否有 __getattr__ 方法。
  3. 如果存在 __getattr__ 方法,則調用該方法,並將屬性名稱作為參數傳遞。
  4. 如果 __getattr__ 方法也未處理該屬性,則會引發 AttributeError

3. 範例

以下是一個簡單的例子來說明 __getattr__ 的實際用法:

class MyClass:
    def __init__(self):
        self.existing_attribute = "I exist!"

    def __getattr__(self, name):
        # 當屬性不存在時,返回一條信息
        return f"Attribute '{name}' not found!"

# 創建對象
obj = MyClass()

# 訪問存在的屬性
print(obj.existing_attribute)  # I exist!

# 訪問不存在的屬性,觸發 __getattr__
print(obj.some_missing_attribute)  # Attribute 'some_missing_attribute' not found!

4. 與 __getattribute__ 的區別

除了 __getattr__,Python 還有一個相關的方法是 __getattribute__。它們的區別如下:

方法名稱 調用時機 應用場景
__getattr__ 當屬性不存在時才會被調用 用於提供對不存在屬性的默認行為或動態生成屬性。
__getattribute__ 所有屬性訪問(無論屬性是否存在)時都會被調用 用於攔截對所有屬性的訪問,實現更高級別的屬性控制,但需要謹慎使用以避免無限遞歸。

示例區別:

class MyClass:
    def __getattribute__(self, name):
        return f"Accessing attribute '{name}'"

    def __getattr__(self, name):
        return f"Attribute '{name}' not found!"

obj = MyClass()

print(obj.existing_attribute)  # Accessing attribute 'existing_attribute'
print(obj.some_missing_attribute)  # Accessing attribute 'some_missing_attribute'

5. 注意事項

6. 總結

在 Python 中,__getattr__ 是一個魔術方法,用於當屬性不存在時自定義其行為。這使得我們可以動態地處理屬性訪問,並增強類的靈活性。但在使用時需要注意避免無限遞歸問題,並區分其與 __getattribute__ 的使用場景。