La modification du __dict__ d'un objet pour définir ses propriétés est-elle considérée comme Pythonic?

12

J'ai une classe qui gonfle des objets à partir de lignes trouvées dans une base de données (ou une autre source, par exemple MongoDB, un fichier CSV, etc.). Pour définir les propriétés de l'objet, il fait quelque chose comme self.__dict__.update(**properties)ou obj.__dict__.update(**properties).

Est-ce considéré comme Pythonic? Est-ce un bon modèle que je devrais continuer à utiliser, ou est-ce considéré comme une mauvaise forme?

skyler
la source
1
Je ne sais pas si c'est Pythonic, mais c'est certainement plus courant de le faire dans dunder init.
user16764

Réponses:

10

En Python 3.3, un nouveau type a été ajouté types.SimpleNamespace(), et dans la documentation il est décrit ainsi:

Le type est à peu près équivalent au code suivant:

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

Notez la __init__méthode du type; vous ne pouvez pas obtenir une meilleure approbation de la technique que la documentation Python.

Martijn Pieters
la source
Bien qu'il SimpleNamespacesoit assez différent de la plupart des types, il n'a pas d'ensemble d'attributs fixe.
7
Eh bien, en parlant de la documentation Python, de docs.python.org/2/library/stdtypes.html "Un attribut spécial de chaque module est __dict__. C'est le dictionnaire contenant la table des symboles du module. La modification de ce dictionnaire changera en fait le symbole du module , mais l'affectation directe à l' __dict__attribut n'est pas possible (vous pouvez écrire m.__dict__['a'] = 1, ce qui définit m.aêtre 1, mais vous ne pouvez pas writem.__dict__ = {}). La modification __dict__directe n'est pas recommandée ", c'est ce qui m'a initialement incité à poser cette question.
skyler
@skyler: notez que cela ne mentionne que l' espace de noms du module . La globals()fonction renvoie le même espace de noms, et il existe généralement de meilleures façons de résoudre les problèmes que de définir des globaux de manière dynamique, d'où l'avertissement.
Martijn Pieters