在Python中,可以通过重写魔法方法__getitem__
、__setitem__
、__delitem__
来实现创建类似于序列和映射的类,这些魔法方法可以让我们实现像list、tuple、dict等内建类型的访问。
一、工作原理:
当我们对类的属性item进行下标操作时,会被__getitem__、__setitem__、__delitem__拦截,也就是这三个魔法方法会自动触发,从而进行我们在方法中设定的操作,如获取值、赋值、修改值、删除值等。
__getitem__:定义对类的实例调用self[key]的行为。
__setitem__:定义对类的实例调用self[key] = value的行为。
__delitem__:定义对类的实例调用del self[key]的行为。
__len__:计算序列长度。
二、实例操作
具体来说,__getitem__(self,key)
方法被用来获取键对应的值,而__setitem__(self,key,value)
方法则被用来设置给定键的值。这两个方法都是python魔法方法的一种。例如,我们可以通过重写__getitem__
和__setitem__
方法来实现一个简单的字典类:
1 class MyList(object): 2 3 def __init__(self): 4 self.dict = {} 5 6 def __getitem__(self, key): 7 return self.dict[key] 8 9 def __setitem__(self, key, value): 10 self.dict[key] = value 11 12 def __delitem__(self, key): 13 del self.dict[key]
这个类中,我们使用了一个字典来存储键值对,然后用__getitem__
和__setitem__
方法来实现获取和设置键对应的值的功能;_delitem__
方法,用来删除一个键值对。例如:
1 obj = MyDict() 2 3 obj['a'] = 1 # 调用 __setitem__ 方法 4 5 print(obj['a']) # 调用 __getitem__ 方法,输出 1 6 7 del obj['a'] # 调用 __delitem__ 方法
还有一个__len__
方法,用来获取序列的长度。
class MyList(object): def __init__(self, *args): self.list = [*args] def __getitem__(self, key): return self.list[key] def __setitem__(self, key, value): print("我被调用了") self.list[key] = value def __delitem__(self, key): del self.list[key] def __len__(self): return len(self.list) l = MyList(1,2,3,4,5) l[2] = 2 print(len(l)) # 调用 __len__ 方法,输出 2,注意点:len(实例化对象)触发类里的len方法,若len(l.list)不会触发__len__,使用的是python底层的__len__
三、结论
只要是del删除就会触发__delitem__,只要是obj[key]就会触发__getitem__,只要是obj[key] = value就会触发__setitem__,可模拟字典、列表、元组操作,但这些魔法方法接收的参数已被底层定死,
自定义时不能多或少接收。利用触发机制,比如del时我要设置值,都是可以的,只是不符合现实逻辑,我只是想说,利用好触发机制,实现自定义操作。
只要是len()就会触发__len__。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端