Created
November 14, 2012 20:46
-
-
Save ojacobson/4074689 to your computer and use it in GitHub Desktop.
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
def jsonizable(atoms=(), lists=(), objects=()): | |
"""Adds a `to_json` method to decorated classes: | |
>>> @jsonizable(atoms=['name', 'age']) | |
... class Example(object): | |
... def __init__(self, name, age): | |
... self.name = name | |
... self.age = age | |
... | |
>>> e = Example('bob', 37) | |
>>> e.to_json() | |
{'name': 'bob', 'age': 37} | |
JSON fields containing nested lists or collections must be handled specially: | |
>>> @jsonizable(atoms=['name']) | |
... class Person(object): | |
... def __init__(self, name): | |
... self.name = name | |
... | |
>>> @jsonizable(lists=['students'], objects=['teacher']) | |
... class Classroom(object): | |
... def __init__(self, students, teacher): | |
... self.students = students | |
... self.teacher = teacher | |
... | |
>>> students = [Person('bob'), Person('anne')] | |
>>> teacher = Person('clarice') | |
>>> classroom = Classroom(students, teacher) | |
>>> classroom.to_json() | |
{'students': [{'name': 'bob'}, {'name': 'anne'}], 'teacher': {'name': 'clarice'}} | |
The generated to_json method returns a `dict`, allowing callers to further | |
manipulate the JSON data before returning it. | |
The fields to include in the resulting `dict` are given by the optional | |
`atoms`, `lists`, and `objects` keyword arguments. Values from attributes | |
named in `atoms` will be included in the dict using the equivalent of | |
`getattr(self, atom_attr)`. Values of attributes named in `lists` will be | |
turned into lists using the equivalent of | |
`[v.to_json for v in getattr(self, list_attr)]`. Values of attributes named | |
in `objects` will be turned into nested JSON values using the equivalent | |
of `getattr(self, obj_attr).to_json() if getattr(self, obj_attr) else None`. | |
""" | |
def to_json(self): | |
json_data = dict() | |
for attribute in atoms: | |
json_data[attribute] = getattr(self, attribute) | |
for attribute in lists: | |
value = getattr(self, attribute) | |
if value is None: | |
json_data[attribute] = None | |
else: | |
json_data[attribute] = [element.to_json() for element in value] | |
for attribute in objects: | |
value = getattr(self, attribute) | |
if value is None: | |
json_data[attribute] = None | |
else: | |
json_data[attribute] = value.to_json() | |
return json_data | |
def decorator(cls): | |
cls.to_json = to_json | |
return cls | |
return decorator |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment