Тест, если переменная является списком или кортежем

В Python, что состоит в том, чтобы протестировать лучший способ, если переменная содержит список или кортеж? (т.е. набор)

isinstance() столь злой, как предложенный здесь? http://www.canonical.org/~kragen/isinstance/

Обновление: наиболее распространенная причина я хочу отличить список от строки, состоит в том, когда у меня есть некоторое неограниченно долго глубокое вложенное дерево / структура данных списков списков списков строк и т.д., которые я исследую с рекурсивным алгоритмом, и я должен знать, когда я поразил "листовые" узлы.

214
задан smci 1 July 2019 в 08:07
поделиться

6 ответов

Продолжайте использовать isinstance, если вам это нужно. Это в некоторой степени зло, поскольку исключает пользовательские последовательности, итераторы и другие вещи, которые могут вам действительно понадобиться. Однако иногда нужно вести себя по-другому, если кто-то, например, передает строку. Я бы предпочел явную проверку на str или unicode, например, так:

import types
isinstance(var, types.StringTypes)

N.B. Не путайте types.StringType с types.StringTypes. Последний включает в себя объекты str и unicode.

Модуль types многие считают устаревшим в пользу проверки непосредственно типа объекта, поэтому, если вы не хотите использовать вышеупомянутый модуль, вы можете альтернативно проверить явным образом str и unicode, например, так:

isinstance(var, (str, unicode)):

Редактировать:

Еще лучше:

isinstance(var, basestring)

Конец редактирования

После любого из этих вариантов можно вернуться к поведению, как будто вы получаете нормальную последовательность, позволяя непоследовательностям вызывать соответствующие исключения.

Видите ли, "зло" в проверке типов не в том, что вы можете захотеть вести себя по-другому для определенного типа объектов, а в том, что вы искусственно ограничиваете свою функцию от правильных действий с неожиданными типами объектов, которые в противном случае делали бы правильные вещи. Если у вас есть конечный fallback, который не проверяется на тип, вы снимаете это ограничение. Следует отметить, что слишком большая проверка типов - это запах кода, который указывает на то, что вам, возможно, следует провести рефакторинг, но это не означает, что вы должны избегать ее с самого начала.

94
ответ дан 23 November 2019 в 04:22
поделиться

Нет ничего плохого в использовании Isinstance , пока он не является избыточным. Если переменная должна быть только списком / кортеж, затем документируйте интерфейс и просто используйте его как таковые. В противном случае чек совершенно разумный:

if isinstance(a, collections.Iterable):
    # use as a container
else:
    # not a container!

Этот тип проверки имеет несколько хороших случаев использования, такие как со стандартной строкой StartSwith / Эндонсвит методы (хотя для того, чтобы быть точным Реализуются в C в CPYPHON, используя явную проверку, чтобы увидеть, если это кортеж - есть более одного способа решения этой проблемы, как указано в статье, которую вы ссылаетесь).

Явная проверка часто лучше, чем пытаться использовать объект в качестве контейнера и обрабатывать исключение - это может привести к тому, что всевозможные проблемы с кодом запускаются частично или без необходимости.

38
ответ дан 23 November 2019 в 04:22
поделиться

Документируйте аргумент по мере необходимости последовательности и использовать его как последовательность. Не проверяйте тип.

14
ответ дан 23 November 2019 в 04:22
поделиться

Если вам просто нужно знать, можно ли использовать нотацию foo [123] с переменной, вы можете проверить наличие атрибута __ getitem __ (который вызывает Python при доступе по индексу) с помощью hasattr (foo, '__getitem __')

3
ответ дан 23 November 2019 в 04:22
поделиться

Python использует «набрать уток», то есть, если переменная кваки, как утка, она должна быть уткой. В вашем случае вы, вероятно, хотите, чтобы это было иначебно, или вы хотите получить доступ к пункту в определенном индексе. Вы должны просто сделать это: т. Е. Используйте объект в для var: или VAR [IDX] Внутри Попробуйте блок, и если вы получите исключение, это разве «Утка ...

8
ответ дан 23 November 2019 в 04:22
поделиться

В принципе, я согласен с Игнасио выше, но вы также можете использовать тип , чтобы проверить, не является ли что-то кортежом или списком.

>>> a = (1,)
>>> type(a)
(type 'tuple')
>>> a = [1]
>>> type(a)
(type 'list')
1
ответ дан 23 November 2019 в 04:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: