hechengQAQ

导航

 

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

 

posted on 2023-03-22 23:06  hechengQAQ  阅读(31)  评论(0编辑  收藏  举报