Custom container (Container)
After the introduction in the previous chapter, we know that in Python, common container types are: dict, tuple, list, string. The concepts of containerized and immutable containers are also mentioned. Among them, tuple and string are immutable containers, and dict and list are mutable containers. The difference between a mutable container and an immutable container is that once an immutable container is assigned a value, an element in it cannot be modified. Of course, for a detailed introduction, you can read back to the previous article, which has pictures and texts.
So here’s a question first, are these data structures enough for us to develop and use? What should we do when it is not enough, or when there are some special needs that cannot be solved using these basic containers alone?
At this time, we need to customize the container, so how should we do it?
Function | Description |
Custom immutable container type | Requires definition_ _len__ and __getitem__ methods |
Customized variable type container | Add definitions __setitem__ and __delitem__ |
Custom data types need to be iterated | Need to define __iter__ |
Return the length of the custom container | Need to be implemented_ _len__(self) |
Custom containers can call self[key]. If the key type is wrong, TypeError will be thrown. If the value corresponding to the key cannot be returned, this method should throw ValueError | Need to implement __getitem__(self, key) |
When executing self[key] = value | The call is __setitem__(self, key, value) this method |
When executing del self[key] method | In fact, the method called is __delitem__(self, key) |
When you want your container to be able to execute for x in container: or use iter(container) | You need to implement __iter__(self), which returns an iterator |
Let’s take a look at using the above magic method to implement a data structure in the Haskell language:
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- class FunctionalList: ''' 实现了内置类型list的功能,并丰富了一些其他方法: head, tail, init, last, drop, take''' def __init__(self, values=None): if values is None: self.values = [] else: self.values = values def __len__(self): return len(self.values) def __getitem__(self, key): return self.values[key] def __setitem__(self, key, value): self.values[key] = value def __delitem__(self, key): del self.values[key] def __iter__(self): return iter(self.values) def __reversed__(self): return FunctionalList(reversed(self.values)) def append(self, value): self.values.append(value) def head(self): # 获取第一个元素 return self.values[0] def tail(self): # 获取第一个元素之后的所有元素 return self.values[1:] def init(self): # 获取最后一个元素之前的所有元素 return self.values[:-1] def last(self): # 获取最后一个元素 return self.values[-1] def drop(self, n): # 获取所有元素,除了前N个 return self.values[n:] def take(self, n): # 获取前N个元素 return self.values[:n]