Use the setattr() Function to Set Attributes of a Class in Python. Python's setattr() function is used to set values for the attributes of a class. In programming, where the variable name is not static, the setattr() method comes in very handy as it provides ease of use.
__dict__ in Python represents a dictionary or any mapping object that is used to store the attributes of the object. They are also known as mappingproxy objects.
Sure, something like this:
class Employee(object):
def __init__(self, initial_data):
for key in initial_data:
setattr(self, key, initial_data[key])
Update
As Brent Nash suggests, you can make this more flexible by allowing keyword arguments as well:
class Employee(object):
def __init__(self, *initial_data, **kwargs):
for dictionary in initial_data:
for key in dictionary:
setattr(self, key, dictionary[key])
for key in kwargs:
setattr(self, key, kwargs[key])
Then you can call it like this:
e = Employee({"name": "abc", "age": 32})
or like this:
e = Employee(name="abc", age=32)
or even like this:
employee_template = {"role": "minion"}
e = Employee(employee_template, name="abc", age=32)
Setting attributes in this way is almost certainly not the best way to solve a problem. Either:
You know what all the fields should be ahead of time. In that case, you can set all the attributes explicitly. This would look like
class Employee(object):
def __init__(self, name, last_name, age):
self.name = name
self.last_name = last_name
self.age = age
d = {'name': 'Oscar', 'last_name': 'Reyes', 'age':32 }
e = Employee(**d)
print e.name # Oscar
print e.age + 10 # 42
or
You don't know what all the fields should be ahead of time. In this case, you should store the data as a dict instead of polluting an objects namespace. Attributes are for static access. This case would look like
class Employee(object):
def __init__(self, data):
self.data = data
d = {'name': 'Oscar', 'last_name': 'Reyes', 'age':32 }
e = Employee(d)
print e.data['name'] # Oscar
print e.data['age'] + 10 # 42
Another solution that is basically equivalent to case 1 is to use a collections.namedtuple
. See van's answer for how to implement that.
You can access the attributes of an object with __dict__
, and call the update method on it:
>>> class Employee(object):
... def __init__(self, _dict):
... self.__dict__.update(_dict)
...
>>> dict = { 'name': 'Oscar', 'lastName': 'Reyes', 'age':32 }
>>> e = Employee(dict)
>>> e.name
'Oscar'
>>> e.age
32
Why not just use attribute names as keys to a dictionary?
class StructMyDict(dict):
def __getattr__(self, name):
try:
return self[name]
except KeyError as e:
raise AttributeError(e)
def __setattr__(self, name, value):
self[name] = value
You can initialize with named arguments, a list of tuples, or a dictionary, or individual attribute assignments, e.g.:
nautical = StructMyDict(left = "Port", right = "Starboard") # named args
nautical2 = StructMyDict({"left":"Port","right":"Starboard"}) # dictionary
nautical3 = StructMyDict([("left","Port"),("right","Starboard")]) # tuples list
nautical4 = StructMyDict() # fields TBD
nautical4.left = "Port"
nautical4.right = "Starboard"
for x in [nautical, nautical2, nautical3, nautical4]:
print "%s <--> %s" % (x.left,x.right)
Alternatively, instead of raising the attribute error, you can return None for unknown values. (A trick used in the web2py storage class)
say for example
class A():
def __init__(self):
self.x=7
self.y=8
self.z="name"
if you want to set the attributes at once
d = {'x':100,'y':300,'z':"blah"}
a = A()
a.__dict__.update(d)
I think that answer using settattr
are the way to go if you really need to support dict
.
But if Employee
object is just a structure which you can access with dot syntax (.name
) instead of dict syntax (['name']
), you can use namedtuple like this:
from collections import namedtuple
Employee = namedtuple('Employee', 'name age')
e = Employee('noname01', 6)
print e
#>> Employee(name='noname01', age=6)
# create Employee from dictionary
d = {'name': 'noname02', 'age': 7}
e = Employee(**d)
print e
#>> Employee(name='noname02', age=7)
print e._asdict()
#>> {'age': 7, 'name': 'noname02'}
You do have _asdict()
method to access all properties as dictionary, but you cannot add additional attributes later, only during the construction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With