學習Python魔法方法:一個簡單的解釋

PHPz
發布: 2024-08-09 06:44:42
原創
749 人瀏覽過

Learn Python Magic Methods: A Simple Explanation

理解 Python 中的魔術方法

Python 中的魔法方法,也稱為 dunder 方法(因為它們的名稱開頭和結尾都有雙下劃線),允許我們定義物件的各種操作的行為。它們支援自訂行為,並使我們的類別表現得像內建類型。在這篇部落格中,我們將探索不同類別的魔術方法,提供詳細的解釋,並給出實際的範例和用例。

1. 屬性存取方法

這些神奇方法控制如何存取、修改或刪除物件的屬性。

__getattr__ 和 __getattribute__

  • __getattr__:在物件中找不到屬性時呼叫。

  • __getattribute__:無條件呼叫以存取任何屬性。

範例:使用日誌記錄自訂屬性存取

class LoggedAttributes:
    def __init__(self, name):
        self.name = name

    def __getattr__(self, item):
        print(f"Accessing non-existent attribute: {item}")
        return None

    def __getattribute__(self, item):
        print(f"Getting attribute: {item}")
        return super().__getattribute__(item)

# Usage
obj = LoggedAttributes("Alice")
print(obj.name)  # Output: Getting attribute: name\nAlice
print(obj.age)   # Output: Accessing non-existent attribute: age\nNone
登入後複製

實際用例: 在偵錯場景中記錄屬性訪問,以追蹤屬性被存取或修改的時間和方式。

__setattr__ 和 __delattr__

  • __setattr__:嘗試屬性分配時呼叫。

  • __delattr__:嘗試刪除屬性時呼叫。

範例:帶有驗證的自訂屬性修改

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __setattr__(self, key, value):
        if key == "age" and value < 0:
            raise ValueError("Age cannot be negative")
        super().__setattr__(key, value)

    def __delattr__(self, item):
        if item == "name":
            raise AttributeError("Can't delete attribute 'name'")
        super().__delattr__(item)

# Usage
p = Person("Alice", 30)
p.age = 25  # Works fine
# p.age = -1  # Raises ValueError
# del p.name  # Raises AttributeError
登入後複製

實際用例:在設定或刪除屬性時強制執行驗證規則或限制。

2. 容器方法

這些神奇的方法可以讓你的物件表現得像容器(列表、字典等)。

__len__、__getitem__、__setitem__、__delitem__ 和 __iter__

  • __len__:回容器的長度。

  • __getitem__:擷取給定索引或鍵處的項目。

  • __setitem__:在給定索引或鍵處設定項目。

  • __delitem__:刪除給定索引或鍵處的項目。

  • __iter__:傳回迭代器物件。

範例:自訂類似清單的物件

class CustomList:
    def __init__(self):
        self._items = []

    def __len__(self):
        return len(self._items)

    def __getitem__(self, index):
        return self._items[index]

    def __setitem__(self, index, value):
        self._items[index] = value

    def __delitem__(self, index):
        del self._items[index]

    def __iter__(self):
        return iter(self._items)

    def append(self, item):
        self._items.append(item)

# Usage
cl = CustomList()
cl.append(1)
cl.append(2)
cl.append(3)
print(len(cl))  # Output: 3
print(cl[1])    # Output: 2
for item in cl:
    print(item)  # Output: 1 2 3
登入後複製

實際用例: 建立需要專門行為或其他方法的自訂集合類,同時仍支援標準清單操作。

3. 數值方法與比較方法

這些方法定義類別的物件如何與數字運算和比較互動。

數值方法

  • __add__、__sub__、__mul__、__truediv__、__floordiv__、__mod__、__pow__:定義算術運算。

範例:自訂複數類別

class Complex:
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag

    def __add__(self, other):
        return Complex(self.real + other.real, self.imag + other.imag)

    def __sub__(self, other):
        return Complex(self.real - other.real, self.imag - other.imag)

    def __repr__(self):
        return f"({self.real} + {self.imag}i)"

# Usage
c1 = Complex(1, 2)
c2 = Complex(3, 4)
print(c1 + c2)  # Output: (4 + 6i)
print(c1 - c2)  # Output: (-2 + -2i)
登入後複製

實際用例:實作自訂數字類型,如複數、向量或矩陣。

比較方法

  • __eq__、__ne__、__lt__、__le__、__gt__、__ge__:定義比較運算。

範例:為自訂類別實作全排序

from functools import total_ordering

@total_ordering
class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    def __eq__(self, other):
        return (self.title, self.author) == (other.title, other.author)

    def __lt__(self, other):
        return (self.title, self.author) < (other.title, other.author)

    def __repr__(self):
        return f"{self.title} by {self.author}"

# Usage
book1 = Book("Title1", "Author1")
book2 = Book("Title2", "Author2")
books = [book2, book1]
print(sorted(books))  # Output: [Title1 by Author1, Title2 by Author2]
登入後複製

實際用例:支援對自訂物件進行排序或比較,這在堆疊、二元搜尋樹等資料結構中很有用,或者只是在對自訂物件清單進行排序時很有用。

4. 容器方法:實際用例

帶有不區分大小寫鍵的自訂字典

建立一個類似字典的對象,將鍵視為不區分大小寫。

範例:不區分大小寫的字典

class CaseInsensitiveDict:
    def __init__(self):
        self._data = {}

    def __getitem__(self, key):
        return self._data[key.lower()]

    def __setitem__(self, key, value):
        self._data[key.lower()] = value

    def __delitem__(self, key):
        del self._data[key.lower()]

    def __contains__(self, key):
        return key.lower() in self._data

    def keys(self):
        return self._data.keys()

    def items(self):
        return self._data.items()

    def values(self):
        return self._data.values()

# Usage
cid = CaseInsensitiveDict()
cid["Name"] = "Alice"
print(cid["name"])  # Output: Alice
print("NAME" in cid)  # Output: True
登入後複製

實際用例: 建立字典,其中鍵應被視為不區分大小寫,對於處理使用者輸入、配置設定等很有用。

結論

魔法方法提供了一種強大的方法來自訂 Python 中物件的行為。理解並有效地使用這些方法可以使您的類別更加直觀,並與 Python 的內建函數和運算符無縫整合。無論您是實現自訂數字類型、容器還是屬性存取模式,魔術方法都可以大大增強程式碼的靈活性和功能

以上是學習Python魔法方法:一個簡單的解釋的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!