Python魔法函数容器部分一(__del__,__len__,__getitem__,__setitem__,__delitem__)

为了加深印象,也为了以后能够更好的回忆,还是记录一下。

序列(类似集合,列表,字符串),映射(类似字典)基本上是元素的集合,要实现他们的基本行为(协议),不可变对象需要两个协议,可变对象需要4个协议。

__len__(self):返回元素的数量,(为不可变对象需要的协议之一)

__getitem__(self, key)或者__getitem__(self, index), 返回执行输入所关联的值(为不可变对象需要的协议之一)

__setitem__(self, key, values) 或者 __setitem__(self, index, values) , 设置指定输入的值对应的values

__delitem__ (self, key) 删除指定key的值

__del__, 析构函数当这个类不存在实例对象时执行。

下面我编写一个自定义类似列表的类,实例后该类默认前面有10个None参数,且不能删除前面5个空None。(随口说的,开始写了)

def check_index(index):
    if index < 5:
        raise IndexError('index must greater than 10')


class S_List:
    def __init__(self):
        self.ll = [None] * 10

    def __len__(self):  # 提取参数长度
        return len(self.ll)

    def __getitem__(self, index):  # 取出参数
        return self.ll[index]

    def __setitem__(self, index, value):  # 设置参数
        check_index(index)
        self.ll[index] = value

    def __delitem__(self, index):
        check_index(index)
        self.ll.pop(index)

    def __str__(self):  # 打印对象时,输出列表本身
        return str(self.ll)

    def __del__(self):  # 没有手工删除在程序结束时释放
        print('我被释放了!')


sl = S_List()
del sl[3]

print(isinstance(sl, S_List))
print(f'输出原始数据:{sl}')
sl[6] = 'six'
print(f'修改后原始数据:{sl}')
print(f'随便取一个值:{sl[1]}')
del sl[6]
print(f'第二次修改后原始数据:{sl}')
del sl[3]
# sl[4] = 'oh'
print(sl)

 正常输出:

True
输出原始数据:[None, None, None, None, None, None, None, None, None, None]
修改后原始数据:[None, None, None, None, None, None, 'six', None, None, None]
随便取一个值:None
第二次修改后原始数据:[None, None, None, None, None, None, None, None, None]
[None, None, None, None, None, None, None, None, None]
我被释放了!

 报错提示:

Traceback (most recent call last):
  File "/Users/shijianzhong/Desktop/yunzuan_buy/study_base.py", line 81, in <module>
    del sl[3]
  File "/Users/shijianzhong/Desktop/yunzuan_buy/study_base.py", line 73, in __delitem__
    check_index(index)
  File "/Users/shijianzhong/Desktop/yunzuan_buy/study_base.py", line 53, in check_index
    raise IndexError('index must greater than 10')
IndexError: index must greater than 10
我被释放了!

这个是自定义的一个基本没有什么方法的伪字典,不能增加元素,而且index,count等方法由于没有写入都无法使用。

好的方式是可以继承list或者dict的类,在里面对需要的条件进行修改限制,这样的话,实例出来的对象可以继承原来的全部方法。

这次我可以正真的定义个超级列表,根据我的需要。现在要求这个列表初始化有5个None元素,前面5个元素不能修改,后面添加的元素必须为str

def check_str(params):
    if not isinstance(params, str):
        raise ValueError('parameters must is string')
    
def check_index(index):
    if index < 5:
        raise IndexError('index must greater than 10')

class Super_List(list):
    def __init__(self):
        super(Super_List, self).__init__()      # 调用父类初始化
        self += [None] * 5                      # 对初始化的参数进行修改

    def append(self, *args):                    # 对append进行参数限制
        for i in args:
            check_str(i)
        return super(Super_List, self).append(*args)

    def insert(self, index, *args):              # 对insert的参数(索引及插入元素)进行限制
        check_index(index)  # 判断插入位置
        for i in args:
            check_str(i)
        return super(Super_List, self).insert(index, *args)

    def extend(self, *args):                    # 对扩张的列表元素进行判断
        temp = args[0]
        for i in temp:
            check_str(i)
        super(Super_List, self).extend(*args)
    
    def __delitem__(self, index):                # 对del命令的索引进行判断
        check_index(index)
        super(Super_List, self).__delitem__(index)

    def clear(self):                            # 禁止使用clear命令
        raise TypeError('No permission')

ss_l = Super_List()
print(ss_l)
ss_l.append('1')
ss_l.insert(5, 'a')
ss_l.extend(['a', 'b', 'c'])
ss_l.clear()
print(ss_l)

 写了快半个小时,感觉列表的增加与删除命令很多,所有有一些命令没有重写,但逻辑还是一样的。

如果向在有人访问参数的时候,自动执行某些命令,可以写在__getitem__下面。

写了快半个小时,感觉列表的增加与删除命令很多,所有有一些命令没有重写,但逻辑还是一样的。
[Xiěle kuài bàn gè xiǎoshí, gǎnjué lièbiǎo de zēngjiā yǔ shānchú mìnglìng hěnduō, suǒyǒu yǒu yīxiē mìnglìng méiyǒu chóng xiě, dàn luójí háishì yīyàng de.]
Wrote nearly half an hour, I feel a lot of lists and increase the delete command, the command does not override all have some, but the logic is the same.

猜你喜欢

转载自www.cnblogs.com/sidianok/p/11790087.html