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'
4
  • Maybe is already answered here: stackoverflow.com/questions/6578986/… Commented Jul 31, 2018 at 11:08
  • @FranciscodeBorjaSanchez That link didn't help much. I updated my question with findings Commented Jul 31, 2018 at 11:23
  • 1
    This is a totally valid Python dict already. Why don't you load it directly with ast.literal_eval? Commented Jul 31, 2018 at 11:31
  • @blhsing I tried ast.literal_eval() but that didn't help. Commented Jul 31, 2018 at 11:47

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

8 Comments

prints '<type 'str'>' and error - "string indices must be integers, not str"
what is your 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'}"
is this an actual string? or a print of a dict? can you print type(p) ?
print(type(obj)) ----> <type 'str'>
|
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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.