手撸大模型-基础篇 搞定常用魔术方法

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())来调用对象时触发。将对象实例变成一个可调用的对象,类似于函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值