苦练Python第55天:容器协议的七个魔术方法从入门到精通

前言

大家好,我是 倔强青铜三 。欢迎关注我,微信公众号:倔强青铜三。欢迎点赞、收藏、关注,一键三连!

欢迎来到 苦练Python第55天

今天我们来学习「容器协议」配套的七个魔术方法。掌握它们,你的自定义对象就能像 list、dict 一样被 len()for ... in ...item in objobj[...] 等语法糖直接调用。


📏 1. __len__ ------ 回答"我有多长?"

触发时机

  • 内置函数 len(obj)
  • 某些需要布尔判断的场景(空容器会被当作 False)

作用

返回一个非负整数,表示容器内元素个数。

示例

python 复制代码
class MyBox:
    def __init__(self, *items):
        self._items = list(items)

    def __len__(self):
        return len(self._items)

box = MyBox("apple", "banana")
print(len(box))        # 2
if box:                # 自动调用 __len__
    print("非空盒子")

🔍 2. __getitem__ ------ 按下标或键取值

触发时机

  • obj[key]
  • 切片 obj[start:stop:step]
  • for i in obj: 实际先尝试 __iter__,若不存在则退回到 0,1,2... 的 __getitem__

作用

返回与 key 对应的值;不存在时抛 KeyError(字典语义)或 IndexError(序列语义)。

示例

python 复制代码
class MyBox:
    ...
    def __getitem__(self, key):
        return self._items[key]     # 支持切片、负数索引

print(box[0])        # apple
print(box[-1])       # banana
print(box[::-1])     # ['banana', 'apple']

✏️ 3. __setitem__ ------ 按下标或键赋值

触发时机

  • obj[key] = value

作用

把 value 存到指定位置;越界时抛 IndexError,键不存在时可选择自动添加(字典语义)。

示例

python 复制代码
class MyBox:
    ...
    def __setitem__(self, key, value):
        self._items[key] = value

box[1] = "pear"
print(box[:])        # ['apple', 'pear']

🗑️ 4. __delitem__ ------ 按下标或键删除

触发时机

  • del obj[key]

作用

移除对应元素;不存在抛异常。

示例

python 复制代码
class MyBox:
    ...
    def __delitem__(self, key):
        del self._items[key]

del box[0]
print(len(box))      # 1

🔎 5. __contains__ ------ 回答"我在里面吗?"

触发时机

  • item in obj
  • item not in obj

作用

返回布尔值;若未定义,Python 退而使用线性扫描的 __iter__ + 等值比较,效率低。

示例

python 复制代码
class MyBox:
    ...
    def __contains__(self, item):
        return item in self._items

print("pear" in box)   # True

🔄 6. __iter__ ------ 交出迭代器

触发时机

  • for element in obj:
  • list(obj)tuple(obj)sum(obj) 等需要迭代的地方

作用

返回一个迭代器(对象本身或新迭代器皆可)。若类里没写,Python 会尝试用 0,1,2... 的 __getitem__ 兜底。

示例

python 复制代码
class MyBox:
    ...
    def __iter__(self):
        return iter(self._items)   # 复用 list 的迭代器

for fruit in box:
    print(fruit)   # pear

🔁 7. __reversed__ ------ 反向迭代

触发时机

  • reversed(obj)
  • for x in reversed(obj):

作用

返回一个反向迭代器;若未定义,Python 退而使用 __len__ + __getitem__ 倒序访问,效率差。

示例

python 复制代码
class MyBox:
    ...
    def __reversed__(self):
        return reversed(self._items)

print(list(reversed(box)))   # ['pear']

🧪 实战演练:打造一个小型书架

把上面七个方法一次性用齐,实现一个能用 len()forin[]delreversed() 的迷你书架。

python 复制代码
class Bookshelf:
    def __init__(self):
        self._books = []

    def add(self, book):
        self._books.append(book)

    # 1. 长度
    def __len__(self):
        return len(self._books)

    # 2. 取值
    def __getitem__(self, index):
        return self._books[index]

    # 3. 赋值
    def __setitem__(self, index, book):
        self._books[index] = book

    # 4. 删除
    def __delitem__(self, index):
        del self._books[index]

    # 5. 包含
    def __contains__(self, book):
        return book in self._books

    # 6. 正向迭代
    def __iter__(self):
        return iter(self._books)

    # 7. 反向迭代
    def __reversed__(self):
        return reversed(self._books)

# 使用
shelf = Bookshelf()
shelf.add("Python入门")
shelf.add("流畅的Python")
print(len(shelf))            # 2
print("Python入门" in shelf) # True
print(shelf[1])              # 流畅的Python
shelf[0] = "Python核心编程"
del shelf[1]
for book in shelf:
    print(book)              # Python核心编程
for book in reversed(shelf):
    print(book)              # Python核心编程

📌 小结 & 记忆口诀

  • __len__ 说长度
  • __getitem__ 拿东西
  • __setitem__ 改东西
  • __delitem__ 扔东西
  • __contains__ 查东西
  • __iter__ 顺东西
  • __reversed__ 倒东西

把这七个魔术方法写全,你的自定义类就能无缝融入 Python 的容器语法生态,记得把今天的代码敲三遍。

最后感谢阅读!欢迎关注我,微信公众号倔强青铜三

一键三连(点赞、收藏、关注)!

相关推荐
夜幽青玄9 分钟前
mybatis-plus调用报 org.springframework.dao.DataIntegrityViolationException 错误处理
开发语言·python·mybatis
roykingw36 分钟前
【终极面试集锦】如何设计微服务熔断体系?
java·微服务·面试
胖头鱼的鱼缸(尹海文)39 分钟前
数据库管理-第376期 Oracle AI DB 23.26新特性一览(20251016)
数据库·人工智能·oracle
瑞禧生物ruixibio42 分钟前
4-ARM-PEG-Pyrene(2)/Biotin(2),多功能化聚乙二醇修饰荧光标记生物分子的设计与应用探索
arm开发·人工智能
大千AI助手1 小时前
Huber损失函数:稳健回归的智慧之选
人工智能·数据挖掘·回归·损失函数·mse·mae·huber损失函数
Jay丶1 小时前
聊聊入职新公司两个月,试用期没过这件事
前端·面试
墨利昂1 小时前
10.17RNN情感分析实验:加载预训练词向量模块整理
人工智能·rnn·深度学习
程序员饼总1 小时前
面试官问:说说RocketMQ的零拷贝?
面试
【建模先锋】1 小时前
一区直接写!CEEMDAN分解 + Informer-LSTM +XGBoost组合预测模型
人工智能·lstm·ceemdan·预测模型·风速预测·时间序列预测模型
fsnine1 小时前
YOLOv2原理介绍
人工智能·计算机视觉·目标跟踪