-1

I have a class like that:

class Payload(object):
   def __init__(self, payload__):
       self.__dict__ = json.loads(payload__)

I can read the JSON payloads like that:

json = Payload('{"Test1":"Test2","Test3":{"Test4":true}}')

So I can access the value of Test like that:

print(json.Test1) # result: Test2

but I can't access the value of Test4 which is a sub of Test3

print(json.Test3.Test4) #result: AttributeError: 'dict' object has no attribute 'Test4'

So, the error is AttributeError: 'dict' object has no attribute 'Test4'

Any help would be appreciated.

Thanks!

Mario
  • 1,374
  • 6
  • 22
  • 48

3 Answers3

0

I've solved it!

Thanks to @Stack for linking to Accessing dict keys like an attribute? which had 2 different methods to solve my problem:

  1. Using json.Test3['Test4']
  2. Using the class:

    class AttributeDict(dict):
        def __getattr__(self, attr):
            return self[attr]
        def __setattr__(self, attr, value):
            self[attr] = value
    

By the way, I find that the first method is more easier.

I can now access the value of Test4 like that:

print(json.Test3['Test4'])
Mario
  • 1,374
  • 6
  • 22
  • 48
0

try using :

print(json["Test3"]["Test4"])
ItayBenHaim
  • 163
  • 7
  • Although this code might solve the problem, a good answer requires an explanation how the problem is solved. – BDL Sep 05 '18 at 09:41
0

If your are not disturbed by using the dict notation (using square brackets) instead of the dotted notation, you could simply avoid usage of the Payload class and access every data in you dict this way:

payload = json.loads('{"Test1":"Test2","Test3":{"Test4":true}}')
print(payload['Test1'])  # "Test2
print(payload['Test3']['Test4']) # "True

But if you want to access every data using the dotted notation, you can use the AttrDict class from this answer and provide it to the object_hook parameter of the json.loads method. This make the json module use the provided class instead of dict to map JSON objects to Python objects:

import json


class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self


payload = json.loads(
    '{'
    '  "key_1": "pouet",'
    '  "key_2": {'
    '    "key_21": true,'
    '    "key_22": {'
    '      "key_221": "toto"'
    '    }'
    '  }'
    '}',
    object_hook=AttrDict)


print(payload.key_1)  # "pouet"
print(payload.key_2.key_21)  # True
print(payload.key_2.key_22.key_221) # "toto"

Note that again, the Payload class is useless.

Tryph
  • 5,946
  • 28
  • 49