Синтаксис при разыменовании дерева, поддерживаемого базой данных - PullRequest
2 голосов
/ 24 августа 2011

Я использую MongoDB, поэтому мои кластеры данных находятся в словарях. Некоторые из них содержат ссылки на другие объекты монго. Например, скажем, у меня есть документ Person, в котором есть отдельный документ работодателя. Я хотел бы контролировать доступ к элементам, чтобы автоматически разыменовывать документы. У меня также есть некоторые данные с датами, и, поскольку PyMongo не может хранить информацию о часовом поясе, я хотел бы хранить строковый часовой пояс наряду с временем UTC и иметь доступ к преобразованным временам.

Какой из этих вариантов вам кажется лучшим?

Person = {'employer': ObjectID}
Employer = {'name': str}

Вариант 1: расширенные операции - это методы

  • Примеры
    • print person.get_employer()['name']
    • person.get_employer()['name'] = 'Foo'
    • person.set_employer(new_employer)
  • Pro: синтаксис метода проясняет, что получение работодателя - это не просто доступ к словарю
  • Con: Различия между синтаксисами между ссылочными объектами и нет, что затрудняет нормализацию схемы при необходимости. Увеличение элемента потребует изменения вызывающих абонентов

Вариант 2: все является атрибутом

  • Примеры
    • print person.employer.name
    • person.employer.name = 'Foo'
    • person.employer = new_employer
  • Pro: унифицированный синтаксис для дополненных и неаугментированных
  • ?: Делает неясным, что это подкреплено словарем, но обеспечивает уровень абстракции?
  • Con: Требуется трансформировать словарь в объект, а не в pythonic?

Вариант 3: все является элементом словаря

  • Примеры
    • print person['employer']['name']
    • person['employer']['name'] = 'Foo'
    • person['employer'] = new_employer
  • Pro: унифицированный синтаксис для дополненных и неаугментированных
  • ?: Делает неясным, что некоторые из этих обращений на самом деле являются вызовами методов, но обеспечивает уровень абстракции?
  • Con: Синтаксис элемента словаря подвержен ошибкам типа IMHO.

Ответы [ 2 ]

0 голосов
/ 01 октября 2011

Не бойтесь писать собственный класс, когда это облегчит написание / чтение / отладку / т. Д. Последующего кода

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

Вариант 2 - ваша лучшая ставка - меньше набирать текст, легче читать, создавать свои классы один раз, создавать экземпляры и все готово (нет необходимости изменять ваш словарь).

Вариант 3 на самом деле ничего не покупает по сравнению с вариантом 2 (помимо большего набора текста, плюс возможность опечаток проходить вместо ошибок)

0 голосов
/ 24 августа 2011

Ваши первые 2 варианта потребуют создания класса Person и класса Employer и использования __dict__ для чтения значений и setattr для записи значений.Этот подход будет медленнее, но будет более гибким (вы можете добавить новые методы, проверку и т. Д.)

Самый простой способ - использовать только словари (вариант 3).Это не потребует никакой необходимости.Лично я также считаю, что он наиболее читаемый из 3.

Так что, если бы вы были на вашем месте, я бы использовал вариант 3. Это удобно и просто, и позже его легко расширить, если вы измените свойразум.Если бы мне пришлось выбирать между первыми двумя, я бы выбрал второе (мне не нравится чрезмерное использование геттеров и сеттеров).

PS Я бы держался подальше от person.get_employer()['name'] = 'Foo', независимо от того, что вы делаете.

...