Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Replaces nested attributes on namedtuples

View attr_replace.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
def attr_update(obj, child=None, _call=True, **kwargs):
'''Updates attributes on nested namedtuples.
Accepts a namedtuple object, a string denoting the nested namedtuple to update,
and keyword parameters for the new values to assign to its attributes.
You may set _call=False if you wish to assign a callable to a target attribute.
Example: to replace obj.x.y.z, do attr_update(obj, "x.y", z=new_value).
Example: attr_update(obj, "x.y.z", prop1=lambda prop1: prop1*2, prop2='new prop2')
Example: attr_update(obj, "x.y", lambda z: z._replace(prop1=prop1*2, prop2='new prop2'))
Example: attr_update(obj, alpha=lambda alpha: alpha*2, beta='new beta')
'''
def call_val(old, new):
if _call and callable(new):
new_value = new(old)
else:
new_value = new
return new_value
def replace_(to_replace, parts):
parent = reduce(getattr, parts, obj)
new_values = {k: call_val(getattr(parent, k), v) for k,v in to_replace.iteritems()}
new_parent = parent._replace(**new_values)
if len(parts) == 0:
return new_parent
else:
return {parts[-1]: new_parent}
 
if child in (None, ""):
parts = tuple()
else:
parts = child.split(".")
return reduce(
replace_,
(parts[:i] for i in xrange(len(parts), -1, -1)),
kwargs
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.