Python 中的魔法方法,也称为 dunder 方法(因为它们的名称开头和结尾都有双下划线),允许我们定义对象的各种操作的行为。它们支持自定义行为,并使我们的类表现得像内置类型。在这篇博客中,我们将探索不同类别的魔术方法,提供详细的解释,并给出实际的示例和用例。
这些神奇的方法控制如何访问、修改或删除对象的属性。
__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__:尝试删除属性时调用。
示例:带验证的自定义属性修改
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
实际用例:在设置或删除属性时强制执行验证规则或限制。
这些神奇的方法可以让你的对象表现得像容器(列表、字典等)。
__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
实际用例: 创建需要专门行为或其他方法的自定义集合类,同时仍支持标准列表操作。
这些方法定义类的对象如何与数字运算和比较进行交互。
示例:自定义复数类
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)
实际用例:实现自定义数字类型,如复数、向量或矩阵。
示例:为自定义类实现全排序
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]
实际用例:支持对自定义对象进行排序或比较,这在堆、二叉搜索树等数据结构中很有用,或者只是在对自定义对象列表进行排序时有用。
创建一个类似字典的对象,将键视为不区分大小写。
示例:不区分大小写的字典
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中文网其他相关文章!