Czy modyfikowanie __dict__ obiektu w celu ustawienia jego właściwości jest uważane za Pythonic?

12

Mam klasę, która pompuje obiekty z wierszy znalezionych w bazie danych (lub innym źródle, np. MongoDB, plik CSV itp.). Aby ustawić właściwości obiektu, robi coś takiego jak self.__dict__.update(**properties)lub obj.__dict__.update(**properties).

Czy to uważa się za Python? Czy to dobry wzorzec, którego powinienem nadal używać, czy też jest to uważana za zła forma?

skyler
źródło
1
Nie wiem, czy jest to Python, ale z pewnością bardziej powszechne jest to w dunder init.
user16764,

Odpowiedzi:

10

W Pythonie 3.3 dodano nowy typ types.SimpleNamespace(), aw dokumentacji opisano to w następujący sposób:

Typ jest w przybliżeniu równoważny z następującym kodem:

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))

Zwróć uwagę na __init__metodę typu; nie można uzyskać lepszego poparcia tej techniki niż dokumentacja Python.

Martijn Pieters
źródło
Chociaż SimpleNamespaceróżni się od większości typów tym, że nie ma ustalonego zestawu atrybutów.
7
Cóż, mówiąc o dokumentacji Pythona, z docs.python.org/2/library/stdtypes.html „Specjalnym atrybutem każdego modułu jest __dict__. Jest to słownik zawierający tabelę symboli modułu. Modyfikacja tego słownika faktycznie zmieni symbol modułu tabeli, ale bezpośrednie przypisanie do __dict__atrybutu nie jest możliwe (możesz napisać m.__dict__['a'] = 1, która określa wartość m.a1, ale nie możesz writem.__dict__ = {}). Modyfikacja __dict__bezpośrednia nie jest zalecana ”, co początkowo skłoniło mnie do zadania tego pytania.
skyler
@skyler: pamiętaj, że wspomina tylko o przestrzeni nazw modułów . globals()Zwraca samej przestrzeni nazw, a są zazwyczaj lepsze sposoby na rozwiązanie problemów niż ustawienie globalnych dynamicznie, stąd ostrzeżenie.
Martijn Pieters