hasattr (obj, '__iter__') vs collections

Я видел пару сообщений, в которых рекомендовалось 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 __') по-прежнему лучший вариант.

12
задан Community 23 May 2017 в 12:16
поделиться