Як би ви перевірили, чи є змінною словник у Python?
Це хороше запитання, але, на жаль, більшість upvoted відповідь веде з поганою рекомендацією 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та все ж отримувати правильну поведінку.
Використовуйте інтерфейс
Ви часто чуєте поради OOP, "програма на інтерфейс".
Ця стратегія використовує перевагу поліморфізму 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, і взагалі уникайте перевірки типу, використовуючи інтерфейс безпосередньо.