Является ли изменение объекта __dict__ для установки его свойств считающимся Pythonic?

12

У меня есть класс, который раздувает объекты из строк, найденных в базе данных (или в другом источнике, например, MongoDB, CSV-файл и т. Д.). Чтобы установить свойства объекта, он делает что-то вроде self.__dict__.update(**properties)или obj.__dict__.update(**properties).

Это считается Pythonic? Это хороший шаблон, который я должен продолжать использовать, или это считается плохой формой?

Скайлер
источник
1
Я не знаю, является ли это Pythonic, но, конечно, более распространено делать это в dunder init.
user16764

Ответы:

10

В Python 3.3 был добавлен новый тип, types.SimpleNamespace()и в документации он описан так:

Тип примерно эквивалентен следующему коду:

class SimpleNamespace:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
    def __repr__(self):
        keys = sorted(self.__dict__)
        items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
        return "{}({})".format(type(self).__name__, ", ".join(items))

Обратите внимание на __init__метод типа; Вы не можете получить лучшую поддержку техники, чем документация Python.

Мартейн Питерс
источник
Хотя SimpleNamespaceон отличается от большинства типов тем, что не имеет фиксированного набора атрибутов.
7
Что касается документации по Python, из docs.python.org/2/library/stdtypes.html "Специальный атрибут каждого модуля - __dict__это словарь, содержащий таблицу символов модуля. Изменение этого словаря фактически изменит символ модуля таблица, но прямое присвоение __dict__атрибуту невозможно (вы можете написать m.__dict__['a'] = 1, что определяет m.a1, но вы не можете writem.__dict__ = {}). Прямое изменение __dict__не рекомендуется ", - именно это изначально побудило меня задать этот вопрос.
Скайлер
@skyler: обратите внимание, что здесь упоминается только пространство имен модуля . globals()Функция возвращает то же пространство имен, и, как правило , более эффективные способы решения проблем , чем установка глобалам динамически, поэтому предупреждение.
Мартин Питерс