На этом шаге мы рассмотрим указанный тип контейнеров.
Python позволяет создать как контейнеры-последовательности, аналогичные спискам и кортежам, так и контейнеры-отображения, т. е. словари. Рассмотрим, как это делается.
Чтобы класс смог реализовать функциональность последовательности, нам следует переопределить в нем следующие специальные методы:
Напомним, что строки в Python являются неизменяемыми. Напишем класс MutableString, представляющий строку, которую можно изменять теми же способами, что и список.
# Класс MutableString class MutableString: def __init__(self,s): self.__s = list(s) # Реализуем функциональность итератора def __iter__(self): self.__i = 0 return self def __next__(self): if self.__i > len(self.__s) - 1: raise StopIteration else: a = self.__s[self.__i] self.__i = self.__i + 1 return a def __len__(self): return len(self.__s) def __str__(self): return "".join(self.__s) # Определяем вспомогательный метод, который будет проверять # корректность индекса def __iscorrectindex(self, i): if type(i) == int or type(i) == slice: if type(i) == int and i > self.__len__() - 1: raise IndexError else: raise TypeError # Реализуем функциональность контейнера-списка def __getitem__(self, i): self.__iscorrectindex(i) return self.__s[i] def __setitem__(self, i, v): self.__iscorrectindex(i) self.__s[i] = v def __delitem__(self, i): self.__iscorrectindex(i) del self.__s[i] def __contains__(self, v): return v in self.__s
Проверим класс в действии:
>>> s = MutableString ("Python") >>> print (s[-1]) n >>> s[0] = "J" >>> del s[2:4] >>> print (s) Jyon
Теперь проверим, как наш класс обрабатывает нештатные ситуации. Введем вот такой код, обращающийся к элементу с несуществующим индексом:
>>> s[9] = "u"
В ответ интерпретатор Python выдаст вполне ожидаемое сообщение об ошибке:
Traceback (most recent call last): File "C:\Python34\Files\pr155_1.py", line 48, ins[9] = "u" File "C:\Python34\Files\pr155_1.py", line 35, in __setitem__ self.__iscorrectindex(i) File "C:\Python34\Files\pr155_1.py", line 26, in __iscorrectindex raise IndexError IndexError
На следующем шаге мы продолжим изучение контейнеров.