Существует ли официальный или общеизвестный стандарт минимального интерфейса для "списка"?
Я продолжаю видеть функции и документацию, такие как this и this (чтобы назвать несколько), которые работают на или ссылаться на объекты, похожие на список.
Я прекрасно понимаю, что такое фактический список (dir(list)
), и может вывести, какие (часто меняющиеся) методы из списка необходимы в большинстве ссылок на "подобный списку объект", однако число раз я вижу, что он ссылается, оставил меня со следующим вопросом:
Есть ли стандартный или минимальный минимальный интерфейс для стандартного минимального интерфейса? Является ли это простым, как актуализация __getitem__
, или согласен, что дополнительные вещи, такие как __len__
и __setitem__
также необходимы?
Это может показаться семантикой, но я не могу не думать, что, если не существует стандартного минимального требования к интерфейсу, различные идеи "сходства списков" могут вызвать некоторые проблемы/неправильную обработку. Может быть, это всего лишь незначительный недостаток в написании утиной Python?
Ответы
Ответ 1
Смотрите модуль collections.abc
. Из приведенных там абстрактных базовых классов list
в Python реализует Iterable
, Container
, Sized
, Sequence
и MutableSequence
. Теперь из них Iterable
, Sequence
и MutableSequence
можно было бы случайно назвать list-like.
Однако я бы понял, что термин list-like означает, что он MutableSequence
- имеет, по крайней мере, методы __getitem__
, __setitem__
, __delitem__
и __len__
, ожидая, что он также будет иметь методы mixin, упомянутые в документации, такие как append
.
Если нет необходимости в __setitem__
и __delitem__
, то вместо этого следует называть последовательность - предположение состоит в том, что если что-то принимает последовательность, оно не должно быть изменчивым, таким образом str
, bytes
, tuple
и т.д. также работайте там.
Ваши две ссылки подчеркивают неопределенность термина:
API-интерфейс plotly требует, чтобы объекты list-like
были сериализованы в массив JSON внутренним PlotlyJSONEncoder
, который делегирует большую часть кодирование на Python JSONEncoder
. Однако последний кодирует только tuple
и list
(и подклассы) массиву JSON; таким образом, здесь используется список list
, a tuple
или подклассы. Пользовательский объект последовательности, который не является подклассом, приведет к TypeError: [...] is not JSON serializable
.
unzip recipe, с которым вы связаны, требует объект, который ведет себя как Sequence
, (изменчивость не требуется), таким образом, tuple
или str
, или любой пользовательский объект, реализующий Sequence
, будет там делать.
TL; DR list-like - неопределенный термин. Вместо этого предпочтительнее использовать термины итеративная, последовательность и изменяемая последовательность, теперь, когда они определены в collections.abc
.
Ответ 2
Техническим термином для "списка-подобного объекта" является последовательность. По крайней мере, он поддерживает упорядочение (т.е. Два объекта с одинаковыми элементами, но разные порядки не равны), индексирование (foo[bar]
такое, что bar
является целым числом меньше длины последовательности) и проверочной проверкой (in
) и имеет заданную длину. Он должен поддерживать итерацию, но если нет, то Python будет имитировать ее с помощью индексации.
Ответ 3
Практически в любое время, когда вы видите "-подобный объект" в документации Python, автор сознательно расплывчато. Автор решил, что перечисление всех необходимых интерфейсов будет слишком сложным, и говорит только о том, что некоторые из его интерфейсов требуются. Объект, который реализовал все интерфейсы, гарантированно работает, но в большинстве случаев он будет работать с объектом, который реализует гораздо меньше.
С "подобным списком объекту", вероятно, лучшее, что вы можете сделать, за исключением проверки исходного кода, заключается в том, чтобы определить, нужен ли ему какой-либо из изменяемых интерфейсов. Если ему нужен только доступ только для чтения к списку, вы можете быть уверены, что вам не нужно выполнять какие-либо операции с изменяемой последовательностью.
Если он говорит "подобный списку объект или итератор", вы можете предоставить что-то, что реализует гораздо более простой интерфейс итератора.