Created
December 12, 2014 14:19
-
-
Save jdowner/2d5ea93a78ecfbab4bbc to your computer and use it in GitHub Desktop.
immutable decorator
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
import functools | |
def make_immutable(obj): | |
"""Tries to create an immutable version of an object | |
Converts object into a nested structure of named tuples where possible. | |
Primative types (int, str, float, bool) are unchanged but lists and sets are | |
converted into tuples. Objects are converted into named tuples. | |
This is not a terribly sophisticated function and will work best with | |
objects that contain simple types of data. | |
Arguments: | |
obj - the object to convert | |
Returns: | |
a namedtuple of the same name as the class of the object pass in | |
""" | |
if isinstance(obj, (list, tuple, set)): | |
return tuple(make_immutable(v) for v in obj) | |
if type(obj) in (int, str, float, bool): | |
return obj | |
try: | |
name = obj.__class__.__name__ | |
attrs = {} | |
for key, val in obj.__dict__.items(): | |
value = make_immutable(val) | |
if value is not None: | |
attrs[key] = value | |
return collections.namedtuple(name, attrs.keys())(**attrs) | |
except (AttributeError, TypeError): | |
pass | |
return None | |
def immutable(f): | |
"""Decorator that makes return value immutable""" | |
@functools.wraps(f) | |
def impl(*args, **kwargs): | |
return make_immutable(f(*args, **kwargs)) | |
return impl |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment