Я видел пару сообщений, в которых рекомендовалось isinstance (obj, collections.Sequence)
вместо hasattr (obj, '__iter __')
, чтобы определить, что что-то является списком.
len (объект) или hasattr (object, __iter __)?
Python: проверьте, является ли объект последовательностью
Сначала я был взволнован, потому что проверял, имеет ли объект __ iter __
мне всегда казалось грязным. Но после дальнейшего рассмотрения это все еще кажется лучшим решением, поскольку ни один из тестов isinstance
на коллекции
не дал таких же результатов. collections.Sequence
близок, но возвращает True
для строк.
hasattr(obj, '__iter__')
set([]): True
{}: True
[]: True
'str': False
1: False
isinstance(obj, collections.Iterable)
set([]): True
{}: True
[]: True
'str': True
1: False
isinstance(obj, collections.Iterator)
set([]): False
{}: False
[]: False
'str': False
1: False
isinstance(obj, collections.Sequence)
set([]): False
{}: False
[]: True
'str': True
1: False
Вот код, который я использовал для генерации этого:
import collections
testObjs = [
set(),
dict(),
list(),
'str',
1
]
print "hasattr(obj, '__iter__')"
for obj in testObjs:
print ' %r: %r' % (obj, hasattr(obj, '__iter__'))
print
print "isinstance(obj, collections.Iterable)"
for obj in testObjs:
print ' %r: %r' % (obj, isinstance(obj, collections.Iterable))
print
print "isinstance(obj, collections.Iterator)"
for obj in testObjs:
print ' %r: %r' % (obj, isinstance(obj, collections.Iterator))
print
print "isinstance(obj, collections.Sequence)"
for obj in testObjs:
print ' %r: %r' % (obj, isinstance(obj, collections.Sequence))
print
Я что-то упустил или hasattr (obj, '__iter __')
по-прежнему лучший вариант для проверки, можно ли что-то итерировать?
РЕДАКТИРОВАТЬ: Меня интересует только обнаружение встроенных типов: dict
, list
и set
. ( РЕДАКТИРОВАТЬ: это глупо :))
РЕДАКТИРОВАТЬ: Я должен был включить вариант использования, который заставил меня изучить это . У меня есть функция, которая принимает аргумент, который может быть одним значением или последовательностью. Итак, я хочу определить, что это такое, и превратить его в последовательность, если это одно значение, чтобы я мог обрабатывать его как последовательность после этого.
if hasattr(arg, '__iter__'):
arg= set(arg)
else:
arg= set([arg])
Одно из решений - просто позволить ему генерировать исключение, если объект не может повторяться. Но в моем случае это не работает. Другое решение - использовать что-то вроде:
import collections
def issequenceforme(obj):
if isinstance(obj, basestring):
return False
return isinstance(obj, collections.Sequence)
From: Python: проверить, является ли объект последовательностью
Но для этого требуется, чтобы эта функция была определена, что заставляет меня не использовать ее.
Похоже, например hasattr (arg, '__iter __')
по-прежнему лучший вариант.