Skip to content

Instantly share code, notes, and snippets.

@keyan
Created November 1, 2018 22:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keyan/755a6008e21b9c513bd0ae3e83d52a32 to your computer and use it in GitHub Desktop.
Save keyan/755a6008e21b9c513bd0ae3e83d52a32 to your computer and use it in GitHub Desktop.
Apply a func to a target class to any fields and items nested within an object
def nested_map(obj: object, func, target_class) -> Any:
"""
Accepts any object type and calls .func() on any nested fields of the specified class.
"""
def _nested_map(obj: object) -> None:
"""
Traverse all object fields and list items, calling func when possible.
"""
# Objects without __dict__ cannot have vars() called
if not hasattr(obj, '__dict__'):
return
for field in vars(obj):
field_data = getattr(obj, field)
# Easy case, call func
if isinstance(field_data, target_class):
setattr(obj, field, field_data.func())
# List types need to have each item recursively called
elif isinstance(field_data, list):
[_nested_map(item) for item in field_data]
# Nested object needs to be recursively called
elif hasattr(field_data, '__dict__'):
_nested_map(field_data)
# Without copying the object we might mutate constant fields depending on the func param
obj = deepcopy(obj)
_nested_map(obj)
return obj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment