Est-il possible de créer un objet à partir d'un dictionnaire en python de telle sorte que chaque clé soit un attribut de cet objet?
Quelque chose comme ça:
d = { 'name': 'Oscar', 'lastName': 'Reyes', 'age':32 }
e = Employee(d)
print e.name # Oscar
print e.age + 10 # 42
Je pense que ce serait à peu près l'inverse de cette question: dictionnaire Python à partir des champs d'un objet
def __init__(self,**initial_data)
vous obtenez l'avantage supplémentaire d'avoir une méthode init qui peut également faire des arguments de mots clés (par exemple "e = Employee (name = 'Oscar')" ou simplement prendre un dictionnaire (par exemple "e = Employee ( ** dict) ").Employee(some_dict)
et lesEmployee(**some_dict)
API est incohérent. Le meilleur des deux doit être fourni.()
lieu deNone
, vous pouvez le faire comme si:def __init__(self, iterable=(), **kwargs): self.__dict__.update(iterable, **kwargs)
.[[setattr(self,key,d[key]) for key in d] for d in some_dict]
AddressNotFoundError
(pour renvoyer des données corrigées dans ce cas, plutôt que de faire exploser) - j'ai trouvé fou que quelque chose de si facile en PHP ((object) ['x' => 'y']
) nécessite tellement de cruft en PythonDéfinir des attributs de cette manière n'est certainement pas la meilleure façon de résoudre un problème. Soit:
Vous savez ce que tous les champs devraient être à l'avance. Dans ce cas, vous pouvez définir tous les attributs explicitement. Cela ressemblerait à
ou
Vous ne savez pas ce que tous les champs devraient être à l'avance. Dans ce cas, vous devez stocker les données sous forme de dict au lieu de polluer un espace de noms d'objets. Les attributs sont pour l'accès statique. Ce cas ressemblerait à
Une autre solution qui est fondamentalement équivalente au cas 1 consiste à utiliser un
collections.namedtuple
. Voir la réponse de van pour savoir comment mettre en œuvre cela.la source
Vous pouvez accéder aux attributs d'un objet avec
__dict__
et appeler la méthode de mise à jour dessus:la source
__dict__
est un artefact d'implémentation et ne doit pas être utilisé. De plus, cela ignore l'existence de descripteurs sur la classe.__dict__
est une partie documentée du langage, pas un artefact d'implémentation.setattr
est préférable à l'accès__dict__
direct. Vous devez garder à l'esprit beaucoup de choses qui pourraient conduire à__dict__
ne pas être là ou à ne pas faire ce que vous voulez quand vous l'utilisez__dict__
, mais celasetattr
est pratiquement identique à ce que vous faites réellementfoo.bar = baz
.__dict__
soit déconseillée: docs.python.org/tutorial/classes.html#id2Pourquoi ne pas simplement utiliser les noms d'attributs comme clés d'un dictionnaire?
Vous pouvez initialiser avec des arguments nommés, une liste de tuples, ou un dictionnaire, ou des attributions d'attributs individuels, par exemple:
Sinon, au lieu de déclencher l'erreur d'attribut, vous pouvez renvoyer None pour les valeurs inconnues. (Une astuce utilisée dans la classe de stockage web2py)
la source
Je pense que l'utilisation de la réponse
settattr
est la voie à suivre si vous avez vraiment besoin de soutiendict
.Mais si
Employee
object est simplement une structure à laquelle vous pouvez accéder avec dot syntax (.name
) au lieu de dict syntax (['name']
), vous pouvez utiliser namedtuple comme ceci:Vous disposez d'une
_asdict()
méthode pour accéder à toutes les propriétés en tant que dictionnaire, mais vous ne pouvez pas ajouter d'attributs supplémentaires plus tard, uniquement pendant la construction.la source
dis par exemple
si vous souhaitez définir les attributs à la fois
la source
a.__dict__.update(x=100, y=300, z="blah")
similaire à l'utilisation d'un dict, vous pouvez simplement utiliser des kwargs comme ceci:
la source