魔法方法,也称为 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实际用例:设置或删除属性时强制执行验证规则或限制。
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
实际用例:创建需要专门行为或附加方法的自定义集合类,同时仍然支持标准列表操作。
这些方法定义类的对象如何与数字运算和比较进行交互。
示例:自定义复数类
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)实际用例: 允许对自定义对象进行排序或比较,这在堆、二叉搜索树等数据结构中很有用,或者只是在对自定义对象列表进行排序时有用。
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 的内置函数和运算符无缝集成。无论您是实现自定义数字类型、容器还是属性访问模式,魔术方法都可以极大地增强代码的灵活性和功能性
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3