Last active
February 13, 2019 10:17
-
-
Save adrian-castravete/5883447 to your computer and use it in GitHub Desktop.
Objectify a dictionary, or act as a decorator and objectify the return value of the decorated function. Objectify means getting a dictionary, and assigning attributes to the dictionary given its keys or newer assignments.
This file contains hidden or 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
#!/usr/bin/env python | |
"""Scrap module. | |
Just tiny bits & bolts. | |
.. author: Adrian Castravete | |
""" | |
from functools import wraps | |
def objectify(func): | |
"""Mimic an object given a dictionary. | |
Given a dictionary, create an object and make sure that each of its | |
keys are accessible via attributes. | |
If func is a function act as decorator, otherwise just change the dictionary | |
and return it. | |
:param func: A function or another kind of object. | |
:returns: Either the wrapper for the decorator, or the changed value. | |
Example:: | |
>>> obj = {'old_key': 'old_value'} | |
>>> oobj = objectify(obj) | |
>>> oobj['new_key'] = 'new_value' | |
>>> print oobj['old_key'], oobj['new_key'], oobj.old_key, oobj.new_key | |
>>> @objectify | |
... def func(): | |
... return {'old_key': 'old_value'} | |
>>> obj = func() | |
>>> obj['new_key'] = 'new_value' | |
>>> print obj['old_key'], obj['new_key'], obj.old_key, obj.new_key | |
""" | |
def create_object(value): | |
"""Create the object. | |
Given a dictionary, create an object and make sure that each of its | |
keys are accessible via attributes. | |
Ignore everything if the given value is not a dictionary. | |
:param value: A dictionary or another kind of object. | |
:returns: Either the created object or the given value. | |
""" | |
if isinstance(value, dict): | |
# Build a simple generic object. | |
class Object(dict): | |
def __setitem__(self, key, val): | |
setattr(self, key, val) | |
return super(Object, self).__setitem__(key, val) | |
# Create that simple generic object. | |
ret_obj = Object() | |
# Assign the attributes given the dictionary keys. | |
for key, val in value.iteritems(): | |
ret_obj[key] = val | |
setattr(ret_obj, key, val) | |
return ret_obj | |
else: | |
return value | |
# If func is a function, wrap around and act like a decorator. | |
if hasattr(func, '__call__'): | |
@wraps(func) | |
def wrapper(*args, **kwargs): | |
"""Wrapper function for the decorator. | |
:returns: The return value of the decorated function. | |
""" | |
value = func(*args, **kwargs) | |
return create_object(value) | |
return wrapper | |
# Else just try to objectify the value given. | |
else: | |
return create_object(func) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey adrian !
Thank you for this gist ;) Just a two things, you might change :