Reputation: 5411
I'm writing a python script to collect data from various files into objects with a number of attributes. Each of these attribute can basically be "ok", "bad", or "N/A". Which of the attributes are "N/A" changes according to the parameters I call the script with.
What I want to do is initiate all objects with all these attributes set to "ok" by default, then set those that have not been measured to "N/A" (which is checked by a function returning a list of N/A-attributes). (Then later I collect the data from the files to set the attributes that are "bad" to "bad".)
I thought I could do that via a dictionary, but it doesn't seem to work/access the attributes?
class Myclass:
def __init__(self, ID):
self.ID = ID
self.at1 = "ok"
self.at2 = "ok"
self.at3 = "ok"
self.at4 = "ok"
# there are a LOT more of these attributes
def foo(unused):
for i in range(3):
blurb = Myclass(i)
unused_dic = {"at1":blurb.at1, "at2":blurb.at2,
"at3":blurb.at3, "at4":blurb.at4}
for key in unused:
unused_dic[key] = "N/A"
print blurb.ID, blurb.at1, blurb.at2, blurb.at3, blurb.at4
unused = ["at1","at3"] # this is returned by another function
foo(unused)
The output of this is:
0 ok ok ok ok
1 ok ok ok ok
2 ok ok ok ok
But I would expect and want:
0 N/A ok N/A ok
1 N/A ok N/A ok
2 N/A ok N/A ok
What am I doing wrong, and how can I do it right?
Upvotes: 1
Views: 314
Reputation: 14209
I tried to adopt a style more object-oriented; the setattr
function is what you need:
>>> class Myclass:
def __init__(self, ID):
self.ID = ID
self.at1 = "ok"
self.at2 = "ok"
self.at3 = "ok"
self.at4 = "ok"
def __str__(self):
return str((self.at1, self.at2, self.at3, self.at4))
def unused(self, unused):
for attr in unused:
setattr(self, attr, 'N/A')
print self
>>> unused = ["at1","at3"]
>>> for i in range(3):
m = Myclass(i)
m.unused(unused)
('N/A', 'ok', 'N/A', 'ok')
('N/A', 'ok', 'N/A', 'ok')
('N/A', 'ok', 'N/A', 'ok')
Upvotes: 1
Reputation: 1390
You are not modifying your blurb
object. You are modifying values from unused_dict
.
You need to change your loop to this :
for key in unused:
if key in unused_dic:
setattr(blurb, key, "N/A") # set attribute 'key' of object blurb to "N/A"
Upvotes: 1
Reputation: 1121744
You are not changing the attributes on the instance, only in the dictionary itself. Variables in python are not pointers; changing a string in one place won't make the change visible elsewhere.
You can use setattr()
to dynamically change attributes on an instance:
def foo(unused):
for i in range(3):
blurb = Myclass(i)
for key in unused:
setattr(blurb, key, "N/A")
But you'll have to store the blurb
instance somewhere, the above code just 'drops the ball' so to speak.
Upvotes: 4