Я видел пару сообщений, рекомендующих isinstance(obj, collections.Sequence)
вместо hasattr(obj, '__iter__')
, чтобы определить, что-то есть список.
len (объект) или hasattr (объект, __iter__)?
Python: проверьте, является ли объект последовательностью
Сначала я был взволнован, потому что тестирование, если объект __iter__
всегда казался мне грязным. Но после дальнейшего обзора это все же кажется лучшим решением, потому что ни один из тестов isinstance
на collection
не дает одинаковых результатов. 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__')
все еще лучший вариант для тестирования, если что-то итерабельно?
EDIT: Меня интересуют только встроенные типы: dict
, list
и set
. ( EDIT: это глупо:) )
РЕДАКТИРОВАТЬ: Я должен был включить прецедент, который заставил меня заглядывать в это. У меня есть функция, которая принимает аргумент, который может быть единственным значением или последовательностью. Поэтому я хочу определить, что это такое, и превратить его в последовательность, если это единственное значение, чтобы я мог обработать его как последовательность после этого.
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)
От: Python: проверьте, является ли объект последовательностью
Но для этого требуется, чтобы эта функция была определена, что заставляет меня не хотеть ее использовать.
Похоже, что hasattr(arg, '__iter__')
по-прежнему является лучшим вариантом.