Не используйте dict так часто

Опубликовано 09 September 2016 в Python

У разработчиков на Python наблюдается тенденция использовать дикты там где нужно и там где нет. В основном, это касается передачи данных внутри приложения в виде дикта, вместо создания объекта. Это плохой дизайн, который приводит к целому вороху проблем, самая страшная из которых - такой код невозможно читать.

К примеру, есть код, который вызывает внешнее API и получает в ответ JSON, который уже распарсили в dict. Стоит мне отправлять этот словарь дальше или лучше трансформировать его в экземпляр более специфического класса? Оба варианта возможны. Обычно я предпочитаю использовать классы и объекты, хотя это требует определенных усилий и времени: соответствующий класс надо еще написать.

Кроме времени и усилий, этот подход немного (или много, все зависит от задачи и дикта) снизит производительность приложения. Но его преимущества в большинстве случаев перекрывают этот недостаток. Код гораздо легче читать, он получается самодокументированным и поддерживаемым.

Сравните этот пример:

def return_dict():
    response = responses.get("some_api")
    return response.json()

И этот:

class SomeObject:
    @classmethod
    def from_json(cls, json):
        instance = cls()
        // do magic
        return instance

def return_some_object():
    response = responses.get("some_api")
    return SomeObject.from_json(response.json())

Какой пример легче прочитать и понять? Какой будет легче поддерживать?

Я уверен, что после пары месяцев, полностью забудется что возвращает return_dict. Даже документация не сильно поможет. К тому же, валидировать, что вернула эта функция очень сложно: обычно функция валидирующая дикт выглядит ужасно и представляет из себя гигантский if с кучей ветвлений.

С другой стороны, return_some_object возвращает экземпляр конкретного класса. Если где-то в коде вы получите такой объект, то гораздо проще понять что он из себя представляет, какие данные он содержит и какие методы предоставляет, чем разгадать структуру словаря. И даже если нет ни строчки документации разобраться для чего этот объект нужен довольно просто. В любом случае, гораздо проще работать с экземпляром конкретного класса, а не со словарем.

И последнее, код с классами гораздо проще поддерживать и тестировать. Dict - слишком общий класс и не говорит ничего ни о структуре ни смысле данных, которые содержит. А если словарь содержит еще и вложенные словари (это произойдет практически гарантированно), поддержка кода становится настоящим кошмаром.

---
Возник вопрос? Мне всегда можно написать в Twitter: avkorablev