Как бы вы проверили, является ли переменная словарём в Python?
Это отличный вопрос, но, к сожалению, самый голосующий голос приводит к плохой рекомендации type(obj) is dict.
(Обратите внимание, что вы также не должны использовать dictв качестве имени переменной - это имя встроенного объекта.)
Если вы пишете код, который будет импортироваться и использоваться другими, не предполагайте, что они будут использовать встроенную функцию dict напрямую - делая это предположение, делает ваш код более негибким, и в этом случае создавайте легко скрытые ошибки, которые не будут вызывать ошибку программы. ,
Я настоятельно рекомендую, для целей корректности, удобства обслуживания и гибкости для будущих пользователей, никогда не иметь менее гибких, недиоматических выражений в вашем коде, когда есть более гибкие идиоматические выражения.
isявляется испытанием для идентичности объекта . Он не поддерживает наследование, не поддерживает абстракции и не поддерживает интерфейс.
Поэтому я предоставлю несколько вариантов, которые делают.
Поддержка наследования:
Это первая рекомендация я хотел бы сделать, потому что она позволяет пользователям поставить свой собственный подкласс Dict, или OrderedDict, defaultdictили Counterиз коллекции модуля:
if isinstance(any_object, dict):
Но есть еще более гибкие варианты.
Поддерживающие абстракции:
from collections.abc import Mapping
if isinstance(any_object, Mapping):
Это позволяет пользователю вашего кода использовать собственную пользовательскую реализацию абстрактного отображения, которая также включает в себя любой подкласс класса dict, и при этом получать правильное поведение.
Используйте интерфейс
Вы обычно слышите совет ООП "программа для интерфейса".
Эта стратегия использует преимущества полиморфизма Python или типизации уток.
Поэтому просто попытайтесь получить доступ к интерфейсу, перехватывая определенные ожидаемые ошибки ( AttributeErrorв случае, если их нет, .itemsа TypeErrorв случае, если они itemsне могут быть вызваны) с разумным отступлением - и теперь любой класс, реализующий этот интерфейс, выдаст вам свои элементы (примечание .iteritems()отсутствует в Python 3):
try:
items = any_object.items()
except (AttributeError, TypeError):
non_items_behavior(any_object)
else: # no exception raised
for item in items: ...
Возможно, вы подумали, что использование утки, как это, заходит слишком далеко, допуская слишком много ложных срабатываний, и это может быть в зависимости от ваших целей для этого кода.
Вывод
Не используйте isдля проверки типов для стандартного потока управления. Используйте isinstance, рассматривайте абстракции как Mappingили MutableMapping, и вообще избегайте проверки типов, используя интерфейс напрямую.