В Python, как лучше всего проверить, содержит ли переменная список или кортеж? (т.е. коллекция)
Является ли isinstance()
зло, как предлагается здесь? http://www.canonical.org/~kragen/isinstance/
Обновление: наиболее распространенная причина, по которой я хочу отличить список от строки, это когда у меня есть какое-то неопределенно глубокое вложенное дерево / структура данных списков списков строк и т. Д., Которые я изучаю с помощью рекурсивного алгоритма, и мне нужно чтобы знать, когда я нажал на "лист" узлы.
Ответы:
Идите и используйте,
isinstance
если вам это нужно. Это несколько плохо, поскольку исключает пользовательские последовательности, итераторы и другие вещи, которые вам могут понадобиться. Однако иногда вам нужно вести себя иначе, если кто-то, например, передает строку. Мое предпочтение было бы явно проверитьstr
илиunicode
вот так:NB Не принимайте
types.StringType
заtypes.StringTypes
. Последний включает в себяstr
иunicode
объекты.types
Модуль рассматривается многими устаревшими в пользу просто проверка непосредственно против типа объекта, так что если вы не хотите использовать выше, вы можете альтернативно проверить явно противstr
иunicode
, как это:Редактировать:
Еще лучше:
Конец редактирования
После любого из них вы можете вернуться к поведению, как будто вы получаете нормальную последовательность, позволяя непоследовательности вызывать соответствующие исключения.
Видите, что «зло» в проверке типов заключается не в том, что вы, возможно, захотите вести себя по-разному для определенного типа объектов, а в том, что вы искусственно ограничиваете свою функцию от правильных действий с неожиданными типами объектов, которые в противном случае сделали бы правильные вещи. Если у вас есть последний запасной вариант, который не проверен, вы удалите это ограничение. Следует отметить, что слишком большая проверка типов является запахом кода, который указывает на то, что вы, возможно, захотите провести некоторый рефакторинг, но это не обязательно означает, что вы должны избегать его из getgo.
источник
str
тип, вы должны просто использовать его напрямую, вместо того, чтобы использоватьtypes.StringType
который является просто псевдонимом для него. Но я не думаю, что этот ответ отвечает на заданный вопрос, потому что это было о «коллекции». Если вы не используете Python достаточно новый, чтобы иметьabc
модуль, который вы не можете использоватьisinstance
для проверки, и даже тогда я бы рекомендовал избегать проверки, если это вообще возможно.assert isinstance(u'abc', str) == False
, Я согласен , что лучше проверить по типу непосредственно, а не с помощьюtypes
модуля, ноtypes.StringTypes
делает то , чтоstr
не делает: он возвращает истинуstr
иunicode
объекты. Я отредактирую свой ответ, чтобы предложить двойную проверку в качестве альтернативы.isinstance
зло?» И я привел встречный пример, который (1) является использованием без злаisinstance
, потому что запасной вариант означает, что он не нарушает ducktyping, и (2) является хорошим решением для очень распространенной мотивации людей, желающих проверить, что-тоlist
илиtuple
(то есть, чтобы избавиться от них из строк).class Foo(str): pass
что хочешь?источник
type([]) is list
возвращаетсяTrue
type(x) in [list,tuple]
корочеТам нет ничего плохого в использовании,
isinstance
если это не избыточно. Если переменная должна быть только списком / кортежем, документируйте интерфейс и просто используйте его как таковой. В противном случае проверка вполне разумна:У этого типа проверки есть несколько хороших сценариев использования, например, со стандартными строками метода beginwith / ndswith (хотя, если быть точным, они реализованы в C в CPython с использованием явной проверки, чтобы увидеть, является ли это кортежем - есть более одного способа чтобы решить эту проблему, как указано в статье, на которую вы ссылаетесь).
Явная проверка часто лучше, чем попытка использовать объект в качестве контейнера и обработка исключения - это может вызвать всевозможные проблемы с частичным или ненужным выполнением кода.
источник
set
Объект также итератор, который означает , что в то время как вы можете , конечно , поп - элементы, но это не гарантирует определенный порядок, который является очень опасной вещью для некоторых алгоритмов. В тех случаях, когда порядок элементов имеет значение, алгоритм, использующий этот фрагмент, потенциально может генерировать разные результаты на разных прогонах!Документируйте аргумент как необходимый как последовательность, и используйте его как последовательность. Не проверяйте тип.
источник
Как насчет
hasattr(a, "__iter__")
:?Он сообщает, может ли возвращаемый объект быть повторен как генератор. По умолчанию кортежи и списки могут, но не типы строк.
источник
__iter__
.__iter__
по какой-то причине ...В Python 2.8
type(list) is list
возвращается,false
я бы предложил сравнить тип таким ужасным способом:
(по крайней мере, в моей системе, используя anaconda в Mac OS X Yosemite)
источник
type(list) is list
возвращается,False
потому чтоtype(list)
естьtype
, а неlist
.type(list()) is list
или с любым другим экземпляром списка вернетсяTrue
.Python использует «типизацию утки», то есть, если переменная похожа на утку, это должна быть утка. В вашем случае вы, вероятно, хотите, чтобы он был повторяемым, или хотите получить доступ к элементу по определенному индексу. Вы должны просто сделать это: т.е. использовать объект внутри
for var:
илиvar[idx]
внутриtry
блока, и если вы получите исключение, это не утка ...источник
var
итерация строки произойдет, возможно, с неожиданными результатами.источник
Если вам просто нужно знать, можете ли вы использовать
foo[123]
нотацию с переменной, вы можете проверить наличие__getitem__
атрибута (то, что Python вызывает при доступе по индексу) с помощьюhasattr(foo, '__getitem__')
источник
Должен быть более сложный тест, если вы действительно хотите обрабатывать что-либо как аргумент функции.
Хотя обычно достаточно просто объяснить, что функция ожидает повторяемость, а затем выполнить только проверку
type(a) != type('')
.Также может случиться так, что для строки у вас есть простой путь обработки, или вы будете хороши и сделаете разделение и т. Д., Так что вы не хотите кричать на строки, и если кто-то отправляет вам что-то странное, просто дайте ему исключение.
источник
Другой простой способ узнать, является ли переменная списком или кортежем или вообще проверить тип переменной:
источник
В принципе, я согласен с Игнасио выше, но вы также можете использовать тип, чтобы проверить, является ли что-то кортежем или списком.
источник