How does one build a function that can set an arbitrary value within a dictionary or object? Or in other words, a function that can set any value passed into it.
For example, suppose you have a dictionary like this:
my_dict = {
'foo' : 'bar',
'subdict':{
'sub1' : 1,
'sub2' : 2
}
}
I would like to create a setter function to be used like this:
x = 'x'
# I want to be able to set normal dictionary items
setter(lambda val: val['foo'], my_dict, x)
# And also set subdictionary items
setter(lambda val: val['subdict']['sub1'], my_dict, x)
# Setting items that don't exist would be great too
setter(lambda val: val['new_item'], my_dict, x)
# If my_dict was a class, I'd like to use the same function, like this
setter(lambda val: val.myproperty, my_dict, x)
# Would also be cool if it worked with lists
my_list = [1, 2]
setter(lambda val: val[1], my_list, x)
I don’t seen an obvious way to do this. The naive way below clearly does not work:
def setter(get_attr_func, param, x):
# This doesn't work, but I'd like something like it
get_attr_func(param) = x
I could use the setattr to build something that works for attributes on classes. I could build something else that works for items in dictionaries. But I have no idea how you would do it for sub-dictionaries or sub-objects.
The answer does not have to be in this exact form. Rather, I just want to write a function that sets an arbitrary attribute/item within an object hierarchy.
I decided this was an interesting problem. Primarily, this class collects item or attribute names when you try to get items or attributes from it. It can then use those collected operations to get or set the corresponding value on an object hierarchy. It also has a couple of convenience methods for making a
set_to_xfunction like the one in your example.The class:
Let’s prepare some data and make some setter functions:
Now let’s test them: