- ru
- Language: en
- Documentation version: latest
Протокол последовательности
В самом базовом варианте, протокол последовательности (sequence) включает два метода: __len__ и __getitem__. В более полном варианте также методы: __contains__, __iter__, __reversed__, index и count. Если последовательность изменяема, добавляются еще несколько методов.
Добавим методы __len__ и __getitem__ к классу Network:
In [1]: class Network:
...: def __init__(self, network):
...: self.network = network
...: subnet = ipaddress.ip_network(self.network)
...: self.addresses = [str(ip) for ip in subnet.hosts()]
...:
...: def __iter__(self):
...: return iter(self.addresses)
...:
...: def __len__(self):
...: return len(self.addresses)
...:
...: def __getitem__(self, index):
...: return self.addresses[index]
...:
Метод __len__ вызывается функцией len:
In [2]: net1 = Network('10.1.1.192/30')
In [3]: len(net1)
Out[3]: 2
А метод __getitem__ при обращении по индексу таким образом:
In [4]: net1[0]
Out[4]: '10.1.1.193'
In [5]: net1[1]
Out[5]: '10.1.1.194'
In [6]: net1[-1]
Out[6]: '10.1.1.194'
Метод __getitem__ отвечает не только обращение по индексу, но и за срезы:
In [7]: net1 = Network('10.1.1.192/28')
In [8]: net1[0]
Out[8]: '10.1.1.193'
In [9]: net1[3:7]
Out[9]: ['10.1.1.196', '10.1.1.197', '10.1.1.198', '10.1.1.199']
In [10]: net1[3:]
Out[10]:
['10.1.1.196',
'10.1.1.197',
'10.1.1.198',
'10.1.1.199',
'10.1.1.200',
'10.1.1.201',
'10.1.1.202',
'10.1.1.203',
'10.1.1.204',
'10.1.1.205',
'10.1.1.206']
Так как в данном случае, внутри метода __getitem__ используется список, ошибки отрабатывают корректно автоматически:
In [11]: net1[100]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-11-09ca84e34cb6> in <module>
----> 1 net1[100]
<ipython-input-2-bc213b4a03ca> in __getitem__(self, index)
12
13 def __getitem__(self, index):
---> 14 return self.addresses[index]
15
IndexError: list index out of range
In [12]: net1['a']
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-facd90673864> in <module>
----> 1 net1['a']
<ipython-input-2-bc213b4a03ca> in __getitem__(self, index)
12
13 def __getitem__(self, index):
---> 14 return self.addresses[index]
15
TypeError: list indices must be integers or slices, not str
Реализация остальных методов протокола последовательности вынесена в задания раздела:
__contains__ - этот метод отвечает за проверку наличия элемента в последовательности
'10.1.1.198' in net1
. Если в объекте не определен этот метод, наличие элемента проверяется перебором элементов с помощью __iter__, а если и его нет перевором индексов с __getitem__.__reversed__ - используется встроенной функцией reversed. Этот метод как правило, лучше не создавать и полагаться на то, что функция reversed при отсутствии метода __reversed__ будет использовать методы __len__ и __getitem__.
index - возвращает индекс первого элемента, значение которого равно указаному. Работает полностью аналогично методу index в списках и кортежах.
count - возвращает количество значений. Работает полностью аналогично методу count в списках и кортежах.