Created
November 1, 2018 22:13
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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