Reputation: 304
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.
Upvotes: 0
Views: 3840
Reputation: 996
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()]
Upvotes: 0
Reputation: 1815
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
Upvotes: 0
Reputation: 1291
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])
Upvotes: 2
Reputation: 1392
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)
Upvotes: 1
Reputation:
class User(): def __init__(self, id): self.data = {"id":id} userObj = User(id=12)
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 !
Upvotes: 1