0

My string

"{u'currency_id': u'USD', u'company_id': u'Supplier1', u'name': u'New9', u'created_by': u'Administrator', u'created_date': u'2018-07-31 03:24:41'}"

I know this is not valid JSON.

What I want to do is convert this string into JSON first and then create a python object.

Here's my code.

def _decode_list(self, data):
    rv = []
    for item in data:
        if isinstance(item, unicode):
            item = item.encode('utf-8')
        elif isinstance(item, list):
            item = self._decode_list(item)
        elif isinstance(item, dict):
            item = self._decode_dict(item)
        rv.append(item)
    return rv

def _decode_dict(self, data):
    rv = {}
    for key, value in data.iteritems():
        if isinstance(key, unicode):
            key = key.encode('utf-8')
        if isinstance(value, unicode):
            value = value.encode('utf-8')
        elif isinstance(value, list):
            value = self._decode_list(value)
        elif isinstance(value, dict):
            value = self._decode_dict(value)
        rv[key] = value
    return rv

def execute(self, p):
    print(p)
    obj = json.loads(p, object_hook=self._decode_dict)
    print(obj.name) //error

Error

'unicode' object has no attribute 'name'

Question is, How do I convert this JSON into python obj.

Before passing string to json.loads(), I tried replacing single quotes with double quotes. But that didn't help much.

Update

@Francisco de Borja Sanchez

That link didn't help much.

def execute(self, p):
    p = str(p).replace("'", '"')
    obj = json.loads(p, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))
    print(obj.name)

gives error

Extra data: line 1 column 5 - line 1 column 148 (char 4 - 147)

Without single quotes replacement.

def execute(self, p):
    obj = json.loads(p, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))
    print(obj.name)

gives error

'unicode' object has no attribute 'name'
user1
  • 4,031
  • 8
  • 37
  • 66

2 Answers2

1

You can use ast.literal_eval()

you can do somthing like

import ast

def execute(self, p):
    obj = ast.literal_eval(ast.literal_eval(p))
    print(type(obj)) # <- obj is a dict now
    print(obj['name']) # <- prints object name
0

I apologize if this does not answer your problem(I cannot comment yet). Based on the information provided, I saw that you don't get any error up until you execute this function:

def execute(self, p):
    obj = json.loads(p, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))
    print(obj.name)

The error says: 'unicode' object has no attribute 'name' This means that the error comes from printing the value "obj.name". This means that you HAVE successfully converted your json to a python object. All that you need now is to figure out how to print the name (maybe try to use a getName() function or use obj.__name)

Andbeav
  • 22
  • 7