0

I currently have a dict, where:

one_result = {'name':'Acme', 'description': 'Fun time', 
              'results': {'fun_status': 'Extra', 'fun_title': 'Foo' }
             }

I access the values of this dict in many places in my code and also put many of the results in an array and store it in DB:

class Record(models.Model):
    results = JSONField(default=[], null=True, blank=True)

I would like to keep things DRY and make a Python object out of the result, so I can access the attributes directly, instead of via key_names: result.name VS result['name']

Is there a way that I can create an object that is backed by a dict(), and easily serialized/deserialized into JSON in my db?

Kamilski81
  • 14,409
  • 33
  • 108
  • 161

1 Answers1

2

A simple solution would be adding to the self.__dict__ directly:

class Foo():
    def __init__(self, d):
        for k, i in d.items():
            if isinstance(i, dict):
                self.__dict__[k] = Foo(i)
            else:
                self.__dict__[k] = i

Test case:

f = Foo({"a": "b", "c": {"d": "e"}, "f": ["g", "h", "i"]})
f.a
# 'b'

f.c
# <__main__.Foo at 0x1624c5c0>

f.c.d
# 'e'

f.f
# ['g', 'h', 'i']
r.ook
  • 13,466
  • 2
  • 22
  • 39
  • `setattr(k, i)` or `setattr(k, Foo(i))` would be preferable to working directly with `__dict__`, IMO. – Peter DeGlopper Feb 14 '18 at 18:22
  • @PeterDeGlopper I'm inclined to agree, just because it's more readable to me, but I'm not knowledgeable enough to differentiate the pros and cons. If you could advise the details it would be appreciated. – r.ook Feb 14 '18 at 18:40
  • Basically just standardization and encapsulation. With `setattr` you never have to worry about whether or not the thing you're calling it on has custom attribute behavior - `setattr(some_object, "some_attr_name", some_val)` reliably does the exact same thing as `some_object.some_attr_name = some_val`. – Peter DeGlopper Feb 14 '18 at 18:51