本帖最后由 会飞的小老虎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)
|