How to assign Python Dict Keys to corresponding Python Object Attributes

2.6k views Asked by At

Suppose I have a python class like:

class User:
    name = None
    id = None
    dob = None
    
    def __init__(self, id):
        self.id = id

Now I am doing something like this:

userObj = User(id=12) # suppose I don't have values for name and dob yet
## some code here and this code gives me name and dob data in dictionary, suppose a function call
user = get_user_data() # this returns the dictionary like {'name': 'John', 'dob': '1992-07-12'}

Now, the way to assign data to user object is userObj.name = user['name'] and userObj.dob = user['dob']. Suppose, User has 100 attributes. I will have to explicitly assign these attributes. Is there an efficient way in Python which I can use to assign the values from a dictionary to the corresponding attributes in the object? Like, name key in the dictionary is assigned to the name attribute in the object.

5

There are 5 answers

1
Capie On BEST ANSWER
class User(dict):
    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)
        self.__dict__ = self

and then just get your dictionary and do:

userObj  = User(dictionary)

EDIT: user the function setattr() then

[setattr(userObj, key, item) for key,item in dict.items()]
1
mageos On

First, there is no need to predeclare properties in python.

class Foo:
   bar: int # This actually creates a class member, not an instance member
   ...

If you want to add values to a class instance just use setattr()

d = {
  'prop1': 'value1',
  'prop2': 'value2',
  'prop2': 'value2'
}

x = Foo()

for prop in d.keys():
  setattr(x, prop, d[prop])
0
AudioBubble On

1. Modify the Class definition

class User():
    def __init__(self, id):
        self.data = {"id":id}
userObj = User(id=12)

2. Update the dict()

user = {"name":"Frank", "dob":"Whatever"} # Get the remaining data from elsewhere
userObj.data.update(user) # Update the dict in your userObj
print(userObj.data)
Here you go !
0
Rashid 'Lee' Ibrahim On

Instead of mapping a dict to the variable keys. You can use setattr to set variables in an object.

class User:
    name = None
    id = None
    dob = None

    def __init__(self, id):
        self.id = id

    def map_dict(self, user_info):
        for k, v in user_info.items():
            setattr(self, k, v)

Then for boiler code to use it.


userObj = User(id=12)
user_dict = {
    'name': 'Bob',
    'dob': '11-20-1993',
    'something': 'blah'
}

userObj.map_dict(user_dict)
0
MichaelJanz On

In Case you REALLY need to

This solution is for the case, other solutions dont work for you and you cannot change your class.

Issue

In case you cannot modify your class in any way and you have a dictionary, that contains the information you want to put in your object, you can first get the custom members of your class by using the inspect module:

import inspect
import numpy as np
members = inspect.getmembers(User)

Extract your custom attributes from all members by:

allowed = ["__" not in a[0] for a in members]

and use numpy list comprehention for the extraction itself:

members = np.array(members)["__" not in a[0] for a in members]

Modify the user

So lets say you have the following user and dict and you want to change the users attributes to the values in the dictionary (behaviour for creating a new user is the same)

user = User(1)
dic = {"name":"test", "id": 2, "dob" : "any"}

then you simply use setattr():

for m in members:
setattr(user, m[0], dic[m[0]])

For sure there are better solutins, but this might come in handy in case other things dont work for you

Update

This solution uses the attribute definitions based on your class you use. So in case the dictionary has missing values, this solution might be helpful. Else Rashids solution will work well for you too