1. __len__
-
触发条件:当调用
len()
函数来获取对象的长度或涉及对象长度或大小的操作时,会触发__len__
方法。 -
用途:用于定义对象的“长度”或“大小”,例如自定义的数据结构(如列表、集合、字典等)。
-
示例:
class MyList: def __init__(self): self.items = [] def __len__(self): return len(self.items) my_list = MyList() my_list.items = [1, 2, 3, 4] print(len(my_list)) # 输出 4
2. __getitem__
-
触发条件:当使用索引操作(如
obj[index]
)访问对象时,会触发__getitem__
方法。 -
用途:允许自定义对象支持索引和切片操作。
-
示例:
class MyDict: def __init__(self): self.data = {"a": 1, "b": 2, "c": 3} def __getitem__(self, key): return self.data.get(key, None) my_dict = MyDict() print(my_dict["a"]) # 输出 1 print(my_dict["d"]) # 输出 None
3. __iter__
和 __next__
-
触发条件:
-
__iter__
:当对象被用在迭代的上下文中时,例如for
循环、iter()
函数调用时触发。 -
__next__
:在迭代过程中,每次需要下一个元素时(如next()
函数调用或for
循环的每次迭代)触发。
-
-
用途:用于自定义可迭代对象的行为,实现自定义的迭代器。
-
使用场景及说明
__next__
方法通常与__iter__
方法一起使用,因为迭代器协议要求一个对象必须同时实现这两个方法。当你实现一个自定义的迭代器时,__iter__
方法通常返回迭代器对象本身,而__next__
方法则负责生成下一个值。 -
示例:
class MyIterator: def __init__(self, max_count): self.max_count = max_count self.current = 0 def __iter__(self): # 返回这个对象本身作为迭代器 return self def __next__(self): if self.current < self.max_count: val = self.current self.current += 1 return val else: raise StopIteration # 使用迭代器 my_iter = MyIterator(5) for item in my_iter: print(item) # 输出 0, 1, 2, 3, 4
4. forward
和 __call__
-
forward
:-
触发条件:它是一个自定义的方法名称,需要显式调用。
-
用途:在某些框架(如深度学习框架中)通常被用作“前向传播”的计算逻辑。
-
-
__call__
:-
触发条件:当使用函数调用的语法(如
obj()
)来调用对象时,会触发__call__
方法。 -
用途:将对象实例变成一个可调用的对象,类似于函数。
-
-
示例:
class Model: def forward(self, x): return x ** 2 def __call__(self, x): # 调用时自动调用 forward 方法 return self.forward(x) model = Model() print(model.forward(3)) # 显式调用 forward 方法,输出 9 print(model(3)) # 使用 __call__ 调用,输出 9
5. 总结
魔术方法 | 触发条件 | 使用场景 |
---|---|---|
__len__ | 调用 len() 函数,并将对象作为参数传递时触发。 | 定义对象的长度或大小,例如自定义的数据结构(如列表、集合、字典等)。 |
__getitem__ | 使用索引操作(如 obj[index] )访问对象时触发。切片操作(如 obj[start:stop] )也会触发。 | 支持索引和切片访问,例如自定义的字典或列表类对象。 |
__iter__ | 对象被用在迭代的上下文中时触发,例如 for 循环、iter() 函数调用时触发。 | 定义对象的迭代行为,返回一个迭代器对象(通常是对象本身)。 |
__next__ | 在迭代过程中,每次需要下一个元素时触发,例如 next() 函数调用或 for 循环的每次迭代。 | 实现迭代器的下一个元素的获取逻辑,当迭代结束时抛出 StopIteration 异常。 |
__call__ | 使用函数调用的语法(如 obj() )来调用对象时触发。 | 将对象实例变成一个可调用的对象,类似于函数。 |