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