100 votes

Créer des propriétés d'instance de classe à partir d'un dictionnaire ?

Je suis en train d'importer à partir d'un fichier CSV et d'obtenir des données approximativement sous le format

{ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }

Les noms des champs sont dynamiques. (Eh bien, ils sont dynamiques en ce sens qu'il pourrait y avoir plus que Field1 et Field2, mais je sais que Field1 et Field2 seront toujours là.

J'aimerais pouvoir passer ce dictionnaire dans ma classe allMyFields pour que je puisse accéder aux données ci-dessus en tant que propriétés.

classe allMyFields:
    # Je pense que j'ai besoin d'inclure cela pour permettre l'indication dans Komodo. Je pense.
    self.Field1 = None
    self.Field2 = None

    def __init__(self,dictionary):
        pour k,v in dictionary.items():
            self.k = v
            #bien sûr, cela ne fonctionne pas. J'ai fini par faire cela à la place
            #self.data[k] = v
            #mais ce n'est pas la façon dont je veux accéder aux données.

q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
instance = allMyFields(q)
# Idéalement je pourrais faire ceci.
print q.Field1

Des suggestions? En ce qui concerne pourquoi -- j'aimerais pouvoir profiter de l'indication de code, et l'importation des données dans un dictionnaire appelé data comme je l'ai fait jusqu'à présent ne me le permet pas.

(Puisque les noms de variables ne sont résolus qu'au moment de l'exécution, je vais quand même devoir filer un os à Komodo - je pense que le self.Field1 = None devrait suffire.)

Alors - comment puis-je faire ce que je veux? Ou est-ce que je pigeonne un arbre mal conçu, non-python?

1voto

Une solution simple pour Python >= 3.7 est

field_dict = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }

# Utilisation de dataclasses
from dataclasses import make_dataclass
field_obj = make_dataclass("FieldData", field_dict)(**field_dict)

Ou en utilisant la bibliothèque attrs

# Utilisation de attrs
from attrs import make_class
field_obj = make_class("FieldData", list(field_dict))(**field_dict)

0voto

treefiddy Points 431

Si vous ne souhaitez pas créer une classe initiale et introduire des paramètres dans le constructeur de la classe, une alternative simple serait d'utiliser la méthode dict.update après que la classe ait été créée.

class Foo:
    attr1:str
    attr2:str

d = {'attr1': 'valeur1', 'attr2': 'valeur2'}
foo = Foo()
foo.__ dict __.update(d)

Cette approche offre la flexibilité de maintenir un constructeur propre et une définition de classe simple. Cela vous permet également d'optionnellement remplir manuellement les valeurs d'instance (par exemple foo.attr1 = 'somevalue') lorsque les noms de clés du dictionnaire ne correspondent pas exactement aux noms d'attributs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X