I am facing issues adding class attributes dynamically from a list of strings, consider the following scenario:
This is my class:
class Customer(object):
def __init__(self,**kw):
self.__dict__ = kw
def add_attributes(self,**kw):
self.__dict__.update(kw)
#a group of attributes i want to associate with the class
list = []
list.append("name")
list.append("age")
list.append("gender")
Customer c
for i in list:
# i is the attribute name for the class
c.add_attributes( i = "test")
The issue seems to be the fact that it is treating the attribute name as a string, can someone please advise
-
c = Customer(), thats the error ?James Sapam– James Sapam2014年02月14日 12:53:16 +00:00Commented Feb 14, 2014 at 12:53
-
You have to correct indentation..Grijesh Chauhan– Grijesh Chauhan2014年02月14日 12:54:53 +00:00Commented Feb 14, 2014 at 12:54
-
OT: do not use 'list' as a variable, otherwise this will override standard 'list' function...Don– Don2014年02月14日 13:11:00 +00:00Commented Feb 14, 2014 at 13:11
3 Answers 3
i = "test" is actually converted to {'i':'test'} when passed to **kwargs inside add_attributes, so you need to do something like this:
for i in my_list:
c.add_attributes(**{ i : "test"})
4 Comments
i as the key, and 'test' as the value, then uses the **kw syntax to apply the dictionary as keyword arguments to the c.add_attributes() method.self.__dict__.items() will return key, value pairs.Instead of directly updating __dict__, you can use the setattr builtin method:
for i in list:
# i is the attribute name for the class
setattr(c, i, "test")
In my opinion, playing with internal attributes should be the last resort.
Comments
Instead of a for-loop, you could use dict.fromkeys:
c.add_attributes(**dict.fromkeys(seq, "test"))
since
In [13]: dict.fromkeys(seq, "test")
Out[13]: {'age': 'test', 'gender': 'test', 'name': 'test'}
The ** tells Python to unpack the dict into keyword arguments.
The syntax is explained here and in the docs, here.
By the way, it's best not to use list as a variable name, since it makes it difficult to access the builtin of the same name.