Setting multiple object attributes at once
Asked Answered
D

5

24

Is there a way to set multiple attributes of the same object on a single line, similarly to the way one assigns values to multiple variables?

If I can write

a,b,c=1,2,3

I would like to have something like

someObject.(a,b,c)=1,2,3

Having the same effect as

someObject.a=1
someObject.b=2
someObject.c=3
Dressage answered 13/5, 2015 at 10:37 Comment(1)
I would love to see this as syntax sugar. someObject.(a,b,c)=1,2,3 or (obj1,obj2).a=2,3. Or even (obj1,obj2).(a,b)=(a1,b1),(a2,b2). Don't thinks it's going to happen.Cargian
C
25
def setattrs(_self, **kwargs):
    for k,v in kwargs.items():
        setattr(_self, k, v)

Use this function like this:

setattrs(obj,
    a = 1,
    b = 2,
    #...
)

You can also define this function on class, but that would be less generic (i.e. apply only to that class instances).

Another answer mentions __dict__.update and it can be rewritten to get rid of quotes: obj.__dict__.update(a=1, b=2), however i would not recommend using this method: it doesn't work with properties and it might be hard to notice if you migrate from simple attributes to properties. Basically, __dict__ is "hidden" attribute, implementation detail, which you shouldn't use unless you really want to change implementation in some way.

Calie answered 2/7, 2016 at 11:31 Comment(0)
B
6

First of all you can do the same with object attributes as with other variables:

someObject.a, someObject.b, someObject.c = 1,2,3

Not sure if that is already what you have in mind. If you want to update arbitrary attributes (e.g. in a function) then you could exploit the fact that Python objects store their attributes in a dict, which supports the update() method:

someObject.__dict__.update({"a":1, "b":2, "c":3})

However, this should only be done with care! If one would offer this in a function any attribute of someObject can be changed with that function and even new attributes can be inserted!

Beckner answered 24/6, 2016 at 12:45 Comment(0)
E
3

You can use map to update the attributes of an object with a dictionary of attributes and values.

attrs = {'a': 1, 'b': 2, 'c': 3}

map(lambda item: setattr(someObject, *item), attrs.iteritems())

In Python 3, you need to surround the map call with a list and convert iteritems to items like so.

list(map(lambda item: setattr(someObject, *item), attrs.items()))
Effluent answered 19/1, 2018 at 6:55 Comment(1)
with map, you can't do this in python 3 since map returns an iterator. You may wrap it in tuple() or listAlkyd
C
1
attributes = ['a', 'b', 'c']
values = [1, 2, 3]
for attr, val in zip(attributes, values):
    setattr(obj, attr, val)
Coverlet answered 13/5, 2015 at 10:40 Comment(1)
Yes, this works, but is not more elegant and neither more readable than the three-line version above. What I would like to find out is whether Python has some syntactic sugar that can simplify attribute setting.Dressage
B
0

I have followed @cariocelus answer and it works. However, if you try to set a property that does not exist, the function will create it. I have created a class and a setter that will only work if the variable has already been initialised.

class my_object():
    def __init__(self):
        self.a = 0
        self.b = 0
        
    def set_state(self, **kwargs):
        for k, v in kwargs.items():
            if k in dir(self):
                setattr(self, k, v)
x = my_object
x.set_state(a=1, b=2, c=3)

print(x.c)
AttributeError: 'my_object' object has no attribute 'c'
Butterfield answered 15/5 at 11:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.