__iter__: int и str против списка и кортежа - PullRequest
2 голосов
/ 29 апреля 2020
some_obj = "scalar"
list_like = "__iter__" in dir(some_obj)   # Py2: False; Py3: True

Я использовал его в python 2, чтобы различать guish между «не повторяемыми» (str, int, bool, None) и повторяемыми (list, dict, tuples).

Это больше не работает с python3, поскольку str теперь имеет атрибут __iter__ ( Почему строки в python 2.7 не имеет атрибута "__iter__", но строки в python 3.7 имеют атрибут "__iter__" ).

Ну, часто желательно рассматривать str не как список. Так есть ли лучший путь py2 + py3, чем "__iter__" in dir(some_obj) and not type(some_obj)==str или все случаи проверяются в в этом вопросе ? Я скучаю по другим объектам, которые могут быть оспорены, как str?

Ответы [ 2 ]

0 голосов
/ 29 апреля 2020

Отредактировано: чтобы не путать мой ответ, я цитирую здесь документы.

class collection.ab c .Iterable

AB C для классов, которые предоставить метод iter ().

Проверка isinstance (obj, Iterable) обнаруживает классы, которые зарегистрированы как Iterable или которые имеют метод iter (), но он не обнаруживает классы, которые повторяются с помощью метода getitem (). Единственный надежный способ определить, является ли объект итеративным, - это вызвать iter (obj) .

Это работает в 2 и 3. str, конечно, итерируем.

n1 = 1
s1 = 'abc'

objs = [n1, s1]

for o in objs:
    try:
        iter(o)
    except TypeError:
        print(o, 'is not Iterable!')
    else:
        print(o, 'is Iterable!')

Вывод:

1 is not Iterable!
abc is Iterable!

Цитата взята из здесь

0 голосов
/ 29 апреля 2020

Я не уверен, стоит ли использовать __iter__ для проверки типа, есть лучший выбор для этого типа Iterable.

Это ваше собственное мнение, чтобы разделить группы Я думаю, что самый простой способ - это создать черные списки ...

try:
    from collections.abc import Iterable # py3
except ImportError:
    from collections import Iterable #py2


def check(arg):
    if not isinstance(arg, Iterable):
        return False
    elif isinstance(arg, (str, bytes)):
        return False
    else:
        return True
...