Как отличить последовательность от отображения - PullRequest
6 голосов
/ 04 октября 2010

Я хотел бы выполнить операцию над аргументом, основываясь на том факте, что это может быть объект типа карты или объект типа последовательности. Я понимаю, что ни одна стратегия не будет на 100% надежной для проверки типа, но я ищу надежное решение.

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

def ismap(arg):
   # How to implement this?

def isseq(arg):
   return hasattr(arg,"__iter__")

def operation(arg):
   if ismap(arg):
      # Do something with a dict-like object
   elif isseq(arg):
      # Do something with a sequence-like object
   else:
      # Do something else

Поскольку последовательность можно рассматривать как карту, где ключи являются целыми числами, я должен просто попытаться найти ключ, который не является целым числом? Или, может быть, я мог бы посмотреть на строковое представление? или ...?

UPDATE

Я выбрал ответ SilentGhost, потому что он выглядит наиболее «правильным», но для моих нужд вот решение, которое я в итоге реализовал:

if hasattr(arg, 'keys') and hasattr(arg, '__getitem__'):
   # Do something with a map
elif hasattr(arg, '__iter__'):
   # Do something with a sequence/iterable
else:
   # Do something else

По сути, я не хочу полагаться на ABC, потому что есть много пользовательских классов, которые ведут себя как последовательности и словарь, но все еще не расширяют ABC коллекций python (см. Комментарий @Manoj). Я думал, что атрибут ключей (упомянутый кем-то, кто удалил его / ее ответ) был достаточно хорошим проверкой для сопоставлений.

Классы, расширяющие Азбуку последовательности и сопоставления, также будут работать с этим решением.

Ответы [ 2 ]

10 голосов
/ 04 октября 2010
>>> from collections import Mapping, Sequence
>>> isinstance('ac', Sequence)
True
>>> isinstance('ac', Mapping)
False
>>> isinstance({3:42}, Mapping)
True
>>> isinstance({3:42}, Sequence)
False

collections абстрактные базовые классы (азбука)

1 голос
/ 04 октября 2010

Последовательности имеют метод __add__, который реализует оператор +. Карты не имеют такого метода, поскольку для добавления на карту требуются и ключ, и значение, а оператор + имеет только одну правую часть.

Так что вы можете попробовать:

def ismap(arg):
    return isseq(arg) and not hasattr(arg, "__add__")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...