__getitem__
Let’s look at a simple example to understand:
def __getitem__(self, key): return self.data[key] >>> f = fileinfo.FileInfo("/music/_singles/kairo.mp3") >>> f {'name':'/music/_singles/kairo.mp3'} >>> f.__getitem__("name") '/music/_singles/kairo.mp3' >>> f["name"] '/music/_singles/kairo.mp3'
(1) The __getitem__ dedicated method is very simple. Like the normal methods clear, keys and values, it just redirects to the dictionary, returning the dictionary's values. But how to call it? Oh, you could call __getitem__ directly, but in practice you wouldn't actually do that: I'm doing it here just to show you how it works. The correct way to use __getitem__ is to let Python call it for you.
(2) This looks like the syntax you would use to get a dictionary value, but in fact it returns the value you expect. Here's a hidden link: secretly Python has converted this syntax into a method call of f.__getitem__("name"). This is why __getitem__ is a private class method, not only can you call it yourself, but you can also let Python call it for you by using the correct syntax.
Use slice object
List has a magical slicing method:
>>> range(100)[5:10] [5, 6, 7, 8, 9]
An error was reported for Fib. The reason is that the parameter passed in to __getitem__() may be an int or a slice object, so you have to make a judgment:
class Fib(object): def __getitem__(self, n): if isinstance(n, int): a, b = 1, 1 for x in range(n): a, b = b, a + b return a if isinstance(n, slice): start = n.start stop = n.stop a, b = 1, 1 L = [] for x in range(stop): if x >= start: L.append(a) a, b = b, a + b return L
Try Fib’s slices now:
>>> f = Fib() >>> f[0:5] [1, 1, 2, 3, 5] >>> f[:10] [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
But the step parameter is not processed:
>>> f[:10:2] [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
There is no processing of negative numbers, so there is still a lot of work to be done to correctly implement a __getitem__().
In addition, if the object is viewed as a dict, the parameter of __getitem__() may also be an object that can be used as a key, such as str.
Corresponding to this is the __setitem__() method, which treats the object as a list or dict to assign values to the set. Finally, there is a __delitem__() method for deleting an element.
In short, through the above method, the classes we define behave no differently from the list, tuple, and dict that come with Python. This is entirely due to the "duck typing" of dynamic languages and does not require mandatory inheritance of an interface.