在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__。