setattr for secondary attribute
Bengt Richter
bokr at oz.net
Mon Nov 21 18:32:44 EST 2005
On 20 Nov 2005 20:34:39 -0800, "Alex" <OurLab at gmail.com> wrote:
>I apologize for asking maybe a very trivial question.
>I have a new class object A with slots. One of the slots is, for
>example, object spam. Object spam, in turn, also has slots and one of
>them is attribute eggs. I need to assign a new value to eggs. In other
>words, I need to perform the following:
>
>A.spam.eggs=newValue
>
>The problem is that I have only a string s='spam.eggs' with which to
>work, so I cannot write an expression written above. I tried to use
>setattr:
>
>setattr(A, s, newValue)
>
>but this does not work. It says that object A does not have attribute
>spam.eggs
>
>How would you do it? TIA.
>
A.spam.eggs=newValue
(which would work) really means, if you break it into steps
(A.spam).eggs = newValue
which is
setattr(getattr(A, 'spam'), 'eggs', newValue)
so you just need to break 'spam.eggs' apart and plug in the pieces.
assuming exactly one dot and no spaces to worry about,
s_spam, s_eggs = s.split('.')
then
setattr(getattr(A, s_spam), s_eggs, newValue)
ought to do the job.
If you have more than one dot, e.g., s = 'spam.eggs.ham'
and eggs has a slot ham that you want to assign to, then you need to
loop on getattr for all but the last name, which you use for the setattr.
Something like (untested)
def setbydots(A, s, val):
names = s.split('.')
for name in names[:-1]:
A = getattr(A, name)
setattr(A, names[-1], val)
This should work for no dots or any number, so long as the reference chain is valid.
E.g.,
setbydots(A, 'spam.eggs', newValue)
should accomplish
A.spam.eggs=newValue
as you wanted. I hope ;-)
( posting delayed >12 hrs due to news server prob ;-/ )
Regards,
Bengt Richter
More information about the Python-list
mailing list