Ассоциативный массив vs класс

Рейтинг: 0Ответов: 2Опубликовано: 06.01.2015

Недавно начал разбираться с python и парсингом на нем и обратил внимание, что большинство получаемой информации можно как записать в ассоциативный массив по типу:

{'name': 'MySite', 'url': 'http://mysite.com'}

так и унаследоваться от предварительно созданного класса:

class Site:
    def __init__(self, name, url):
        name = name
        url = url

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

Ответы

▲ 4

dict, сам по себе, будет обрабатываться быстрее (хотя бы потому, что класс сам по себе подразумевает underlying dict, хоть и есть всякие трюки co slots, позволяющие ускорить работу и уменьшить потребление ресурсов), однако использование класса в некоторых случаях просто необходимо. Если очень грубо - надо использовать dict там, где содержание может сильно варьироваться или вообще неизвестно, а также где данные сами по себе представляют пары ключ-значение (например, перевод на конкретный язык: переводимая строка => переведенная строка, больше у единицы информации ничего нет, кроме этих двух сущностей), во всех остальных случаях использовать класс. Если чуть подробнее:

Класс нужно использовать в тех случаях, когда

  • Подразумевается хотя бы минимальная логика (проверка типа, конвертация значений).
  • Логика может появиться. В этом случае лучше положить соломы заранее.
  • Передаваемые данные структурированы и представляют собой конкретную сущность, т.е. это какой-то многократно используемый набор данных, чья структура жестко определена. Например, пишется приложение мобильного оператора - в этом случае у нас наверняка будет такая сущность как сим-карта - у нее есть поля список мобильных номеров, PIN, PUK, ICCID, ID владельца и т.п. В этом случае класс нужно использовать для того, чтобы формализовать конкретные поля, получить автокомплит в IDE и точно знать, к чему обращаться в той или иной части приложения. Формально - это структура из C, которая не выполняет никакой логики, но конкретно эта структура закрепляется с помощью класса.

Преимущество, которое приносит класс - это именно возможность жестко задать необходимые поля. Языку наплевать с чем работать, но с точки зрения архитектуры это очень важное свойство.

Прошу прощения, что у меня такие проблемы с вербализацией.

▲ 1

В общем случае использовать словарь (ассоциативный массив) выгодней с точки зрения потребеления памяти.

С классом можно добавить всякие удобные фичи, например, реализовать методы get_prepared_url и get_upper_name, которые будут приводить в порядок url (проверять, есть http или нету, поставили слеш в конце или нет и т.п.) и возвращать name в верхнем регистре. Таким образом вы можете "спрятать" часть логики в классе и сделать код более красивым.

К тому же у классов есть механизм слотов, который позволит приблизить их по потребелению памяти к словарям.

Если захотеть еще больше экономить память, то можно использовать tuple (кортеж):

data = ('MySite', 'http://mysite.com')

Это почти как список, только еще экономней. Но тогда нам придется обращаться к элементам по их индексам: 0, 1, а это не очень удобно. Тут нам на помощь прийдет namedtuple:

from collections import namedtuple
site_record = namedtuple('SiteRecord', 'name url')
mysite = site_record(name='MySite', url='http://mysite.com')
print mysite.name, mysite.url

Он позволяет хранить данные в памяти, как обычный кортеж, но доставать их по именам.

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