collections.abc предоставляет серию абстрактных базовых классов для контейнера
Этот модуль предоставляет абстрактные базовые классы, которые можно использовать для проверки того, предоставляет ли класс конкретный интерфейс; например, является ли это хешируемым или отображением.
они позволяют вам проверить, имеет ли определенный объект поведение, подобное тому, которое вы проверяете ABC, не обращая внимания на фактическую реализацию.
Например, предположим, что у вас есть функция F, которая что-то делает в соответствии с типом аргумента, вы можете напрямую проверить, является ли он экземпляром списка, кортежа, словаря и т. Д., И выполнять свою работу, но это ограничивает вас только чтобы использовать их, если вы затем создадите свой собственный класс, который имеет аналогичное поведение, чтобы сказать список, в некоторых случаях вы заботитесь и хотите использовать его с F, вы обнаружите, что это не работает, тогда вам нужно изменить F принять ваш класс, но если вместо этого вы проверяете ABC, такая модификация не нужна
Теперь рабочий пример: скажите, что вам нужна функция, которая дает все элементы в четной позиции из списка, тогда вы можете сделать
def even_pos(data):
if isinstance(data,list):
return [data[i] for i in range(0,len(data),2)]
else:
raise ValueError("only a list")
и использовать как
>>> test = list(range(20))
>>> even_pos(test)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>>
нет проблем, но потом вы понимаете, что кортеж - это то же самое, что и список в том, что касается этой функции, вы также можете добавить эту проверку к функции, и все в порядке, но затем ваш друг сказал вам, что хочет использовать ваш функция, но он использует collections.deque
, а затем ваш другой друг сказал ... видишь здесь образец? все упомянутые мной объекты (list, tuple, deque) имеют одно и то же общее, и могут использоваться таким же образом в этой функции примера, и все это поведение сжимается в ABC, поэтому вместо isinstance(data,(list,tuple,collections.deque,...)
вам нужно только isinstance(data,abc.Sequence)
и функция выглядит как
from collections import abc
def even_pos(data):
if isinstance(data,abc.Sequence):
return [data[i] for i in range(0,len(data),2)]
else:
raise ValueError("only a Sequence")
>>> even_pos( list(range(10)) )
[0, 2, 4, 6, 8]
>>> even_pos( tuple(range(10)) )
[0, 2, 4, 6, 8]
>>> even_pos( range(10) ) # in python 3 range don't return a list, but a range object
[0, 2, 4, 6, 8]
>>> even_pos( "asdfghjh" )
['a', 'd', 'g', 'j']
>>>
Теперь вам не нужно знать фактическую реализацию, которая используется, только то, что она имеет желаемое поведение.
person
Copperfield
schedule
29.02.2016