The sequence type in Pyhton supports slicing functions, such as list:
>>> numbers = [1, 2, 3, 4, 5]>>> numbers[1:3[2, 3]
A tuple is also a sequence type and also supports slices.
(a) Can we make the custom type support slicing?
Creating a fully functional sequence type in Python does not require inheritance, as long as a method conforming to the sequence protocol is possible, Python's sequence protocol requires __len__, __getitem__ two methods, such as the following vector class:
fromArrayImportArrayclassVector:type_code='D' def __init__(self, compoments): Self.__components=Array (Self.type_code, compoments)def __len__(self):returnLen (self.__components) def __getitem__(self, index):returnSelf.__components[Index]
We look at the next slice feature in the console:
>>> v1 = Vector ([1, 2, 3])>>> v1[1]2.0>>> v1[1:2]array (' D', [2.0])
Here we delegate the sequence protocol to Self.__compoments (an instance of array), so that we can support the slicing function by implementing __len__ and __getitem__ only.
(b) What is the working principle of python slicing?
Let's look at the behavior of slice through a simple example:
class MySequence: def __getitem__ (self, Index): return Index
>>> S1 = MySequence ()>>> s1[1]1>>> s1[1:4]slice (1, 4, None)>>> s1[1:4:2]slice (1, 4, 2)>>> s1[1:4:2, 7:9] (Slice (1 , 4, 2), Slice (7, 9, None))
We see:
(1) When you enter an integer, __GETITEM__ returns an integer
(2) When entering 1:4 notation, the returned slice (1, 4, None)
(3) Input 1:4:2 notation, return to slice (1, 4, 2)
(4) [] There is a comma, __getitem__ received a tuple
Now let's take a closer look at slice itself:
>>>Slice<class 'Slice'>>>>dir (slice) ['__class__','__delattr__','__dir__','__doc__','__eq__','__format__','__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__','__le__','__lt__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', ' indices ', ' Start ', ' Step ', ' Stop ']
We see the familiar start, stop, step properties, and an unfamiliar indices, with help viewing (Pyhon's console is a valuable tool that we often use DIR,HELP commands for assistance):
Help on method_descriptor:indices (...) (Start, stop, Stride ) and stop and the stride Length of the Extended Slice described by in a manner consistent with the handling of normal slices.
The indices can be used to gracefully handle missing and negative indexes, and slices that exceed the length of the target sequence, and this method reorganizes the input slice tuples, turning start, stop, and step into non-negative numbers and falling within the bounds of the specified length sequence:
Like what:
>>> Slice (None, 2). Indices (5) # target sequence length 5, automatic stop reorganization to 5(0, 5, 2)>> > Slice ( -1, none, none). Indices (5) # will start =-1, stop = none, step = none Reorganization for (4, 5, 1) (4, 5, 1)
Using this method can save a lot of time if there are no underlying sequences as proxies.
We have learned how slice works, and we use it to re-implement the __getitem__ method of the vector class:
fromArrayImportArray fromNumbersImportIntegralclassVector:type_code='D' def __init__(self, compoments): Self.__components=Array (Self.type_code, compoments)def __len__(self):returnLen (self.__components) def __getitem__(self, Index): CLS=type (self)ifisinstance (Slice, index):returnCLS (self.__components[index])#To return an instance of a vector using the CLS construction method elifisinstance (Integral, index):returnSelf.__components[index]Else: RaiseTypeError ("{} indices must be integers or slices". Format (CLS))
Fluent Python:slice