Python魔术方法
文章目录
- Python魔术方法
- 介绍
- 魔术方法的种类
- 魔术方法及其用法
- 初始化与表示
- 属性访问
- 项访问与迭代
- 数值与比较
- 上下文管理
- 结论
介绍
魔术方法(Magic Methods),又称为双下划线方法(Dunder Methods),是Python中以双下划线开头和结尾的方法,例如 __init__
和 __str__
。它们允许我们自定义类在特定情况下的行为,例如使用运算符、内置函数或特定Python语句时。通过魔术方法,我们可以使类的行为更像内置类型,提供更丰富的接口。
魔术方法的种类
魔术方法主要分为以下几类:
- 初始化与表示:
__init__(self, ...)
:构造方法,在创建实例时调用。__del__(self)
:析构方法,在实例即将被销毁时调用。__repr__(self)
:官方字符串表示,用于调试和开发。__str__(self)
:非正式字符串表示,用于print
和str
函数。
- 属性访问:
__getattr__(self, name)
:在对象的属性未找到时调用。__setattr__(self, name, value)
:在属性赋值时调用。__delattr__(self, name)
:在属性删除时调用。
- 项访问与迭代:
__getitem__(self, key)
:使用索引语法获取项时调用。__setitem__(self, key, value)
:使用索引语法设置项时调用。__delitem__(self, key)
:使用索引语法删除项时调用。__iter__(self)
:初始化迭代时调用。__next__(self)
:获取迭代中的下一个项时调用。
- 数值与比较:
__add__(self, other)
:定义加法运算符+
的行为。__sub__(self, other)
:定义减法运算符-
的行为。__mul__(self, other)
:定义乘法运算符*
的行为。__truediv__(self, other)
:定义除法运算符/
的行为。__eq__(self, other)
:定义等于运算符==
的行为。__lt__(self, other)
:定义小于运算符<
的行为。
- 上下文管理:
__enter__(self)
:进入上下文管理块时调用。__exit__(self, exc_type, exc_value, traceback)
:退出上下文管理块时调用。
魔术方法及其用法
初始化与表示
-
__init__(self, ...)
:-
定义:构造方法,在对象实例化时调用,用于初始化对象的属性。
-
示例:
class Animal:def __init__(self, species, age):self.species = speciesself.age = agedog = Animal("Dog", 5)
-
-
__del__(self)
:-
定义:析构方法,在对象实例即将被销毁时调用,常用于清理资源。
-
示例:
class FileHandler:def __init__(self, filename):self.file = open(filename, 'w')def __del__(self):self.file.close()print(f"File {self.file.name} closed.")handler = FileHandler("example.txt")
-
-
__repr__(self)
:-
定义:返回对象的正式字符串表示,通常用于调试和日志记录。
-
示例:
class Person:def __init__(self, name, age):self.name = nameself.age = agedef __repr__(self):return f"Person(name='{self.name}', age={self.age})"person = Person("Alice", 30) print(repr(person))
-
-
__str__(self)
:-
定义:返回对象的非正式字符串表示,用于
print
和str
函数。 -
示例:
class Book:def __init__(self, title, author):self.title = titleself.author = authordef __str__(self):return f"'{self.title}' by {self.author}"book = Book("1984", "George Orwell") print(str(book))
-
属性访问
-
__getattr__(self, name)
:-
定义:在对象的属性未找到时调用,通常用于提供动态属性。
-
示例:
class DynamicAttributes:def __getattr__(self, name):return f"Attribute {name} not found!"obj = DynamicAttributes() print(obj.some_attribute)
-
-
__setattr__(self, name, value)
:-
定义:在属性赋值时调用,允许拦截和定制属性赋值。
-
示例:
class LogAttributes:def __setattr__(self, name, value):print(f"Setting {name} to {value}")self.__dict__[name] = valueobj = LogAttributes() obj.some_attribute = 42
-
-
__delattr__(self, name)
:-
定义:在属性删除时调用,允许拦截和定制属性删除。
-
示例:
class MonitorAttributes:def __delattr__(self, name):print(f"Deleting attribute {name}")object.__delattr__(self, name)obj = MonitorAttributes() obj.some_attribute = "value" del obj.some_attribute
-
项访问与迭代
-
__getitem__(self, key)
:-
定义:使用索引语法获取项时调用。
-
示例:
class CustomList:def __init__(self):self.items = []def __getitem__(self, index):return self.items[index]my_list = CustomList() my_list.items = [1, 2, 3] print(my_list[1])
-
-
__setitem__(self, key, value)
:-
定义:使用索引语法设置项时调用。
-
示例:
class CustomList:def __init__(self):self.items = []def __setitem__(self, index, value):self.items[index] = valuemy_list = CustomList() my_list.items = [1, 2, 3] my_list[1] = 42 print(my_list[1])
-
-
__delitem__(self, key)
:-
定义:使用索引语法删除项时调用。
-
示例:
class CustomList:def __init__(self):self.items = []def __delitem__(self, index):del self.items[index]my_list = CustomList() my_list.items = [1, 2, 3] del my_list[1] print(my_list.items)
-
-
__iter__(self)
:-
定义:初始化迭代时调用,返回迭代器对象。
-
示例:
class MyRange:def __init__(self, start, end):self.start = startself.end = enddef __iter__(self):self.current = self.startreturn selfdef __next__(self):if self.current >= self.end:raise StopIterationcurrent = self.currentself.current += 1return currentfor i in MyRange(1, 5):print(i)
-
-
__next__(self)
:-
定义:获取迭代中的下一个项时调用。
-
示例:
class MyRange:def __init__(self, start, end):self.start = startself.end = enddef __iter__(self):self.current = self.startreturn selfdef __next__(self):if self.current >= self.end:raise StopIterationcurrent = self.currentself.current += 1return currentmy_range = MyRange(1, 5) iterator = iter(my_range) print(next(iterator)) print(next(iterator))
-
数值与比较
-
__add__(self, other)
:-
定义:定义加法运算符
+
的行为。 -
示例:
class Vector:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):return Vector(self.x + other.x, self.y + other.y)def __repr__(self):return f"Vector({self.x}, {self.y})"v1 = Vector(1, 2) v2 = Vector(3, 4) v3 = v1 + v2 print(v3)
-
-
__sub__(self, other)
:-
定义:定义减法运算符
-
的行为。 -
示例:
class Vector:def __init__(self, x, y):self.x = xself.y = ydef __sub__(self, other):return Vector(self.x - other.x, self.y - other.y)def __repr__(self):return f"Vector({self.x}, {self.y})"v1 = Vector(5, 6) v2 = Vector(2, 3) v3 = v1 - v2 print(v3)
-
-
__mul__(self, other)
:-
定义:定义乘法运算符
*
的行为。 -
示例:
class Vector:def __init__(self, x, y):self.x = xself.y = ydef __mul__(self, scalar):return Vector(self.x * scalar, self.y * scalar)def __repr__(self):return f"Vector({self.x}, {self.y})"v = Vector(2, 3) v_scaled = v * 3 print(v_scaled)
-
-
__truediv__(self, other)
:-
定义:定义除法运算符
/
的行为。 -
示例:
class Vector:def __init__(self, x, y):self.x = xself.y = ydef __truediv__(self, scalar):return Vector(self.x / scalar, self.y / scalar)def __repr__(self):return f"Vector({self.x}, {self.y})"v = Vector(4, 8) v_divided = v / 2 print(v_divided)
-
-
__eq__(self, other)
:-
定义:定义等于运算符
==
的行为。 -
示例:
class Vector:def __init__(self, x, y):self.x = xself.y = ydef __eq__(self, other):return self
-
上下文管理
-
__enter__
和__exit__
:class ManagedFile:def __init__(self, name):self.name = namedef __enter__(self):self.file = open(self.name, 'w')return self.filedef __exit__(self, exc_type, exc_value, exc_traceback):self.file.close()with ManagedFile('hello.txt') as f:f.write('Hello, world!')
__enter__
在进入上下文管理块时调用,返回的对象赋值给as
关键字后的变量。__exit__
在退出上下文管理块时调用,负责清理工作,如关闭文件。
结论
魔术方法提供了一种方式,使我们的类能够无缝地集成到Python的语言特性中,从而编写出更具可读性和直观性的代码。理解和使用这些方法,可以大大增强你的Python类的功能和优雅性。