A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 会飞的小老虎1 于 2020-3-20 10:03 编辑

Python中自定义容器

在Python中要自定义一些数据结构,使之能够跟list、dict、tuple表现一样,需要去实现某些协议。这里的协议跟其他语言中所谓的"接口"概念很像,一样的需要你去实现才行,只不过没那么正式而已。

如果要自定义不可变容器类型,只需要定义__len__ 和 __getitem__方法;

如果要自定义可变容器类型,还需要在不可变容器类型的基础上增加定义__setitem__ 和 __delitem__。

如果自定义数据结构还支持"可迭代", 那就还需要定义__iter__。


__len__(self)

需要返回数值类型,以表示容器的长度。该方法在可变容器和不可变容器中必须实现。

__getitem__(self, key)
当你执行self[key]的时候,调用的就是该方法。该方法在可变容器和不可变容器中也都必须实现。
调用的时候,如果key的类型错误,该方法应该抛出TypeError;
如果没法返回key对应的数值时,该方法应该抛出ValueError。
__setitem__(self, key, value)
当你执行self[key] = value时,调用的是该方法。
__delitem__(self, key)
当你执行del self[key]的时候,调用的是该方法。
__iter__(self)
该方法需要返回一个迭代器(iterator)。当你执行for x in container: 或者使用iter(container)时,该方法被调用。
__reversed__(self)
如果想要该数据结构被內建函数reversed()支持,就还需要实现该方法。
__contains__(self, item)
如果定义了该方法,那么在执行item in container 或者 item not in container时该方法就会被调用。
如果没有定义,那么Python会迭代容器中的元素来一个一个比较,从而决定返回True或者False。
__missing__(self, key)
dict字典类型会有该方法,它定义了key如果在容器中找不到时触发的行为。
比如d = {'a': 1}, 当你执行d[notexist]时,d.__missing__('notexist')就会被调用。


模拟实现列表对象
[Python] 纯文本查看 复制代码
class Queryset(object):
    def __init__(self):
        self.data = []

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

    def __getitem__(self, item):
        return self.data[item.start:item.stop:item.step]

    def __setitem__(self, key, value):
        if isinstance(key, int):
            raise RuntimeError("数据类型错误")
        self.data[key] = value

    def __contains__(self, item):
        if item in self.data:
            return True
        else:
            return False

    def __reversed__(self):
        self.data.sort(reverse=True)
        return self.data

    def __iter__(self):
        return self.data.__iter__()

    def append(self, item):
        self.data.append(item)

    def remove(self, item):
        self.data.remove(item)

    def __str__(self):
        return self.data


if __name__ == '__main__':
    q = Queryset()
    q.append(1)
    q.append(2)
    q.append(3)
    q.append(4)
    print(1 in q)
    print(q[:2])
    for i in q:
        print(i)







0 个回复

您需要登录后才可以回帖 登录 | 加入黑马