Исключение Python ValueError не поймано должным образом

itemэто словарь Python

print item.get('body')

в некоторых случаях дает следующий вывод:

"1211V1"

однако item.get('body') в основном имеет строку юникода в формате:

u'{"points_token_id":"327727a0-3909-4132-8fa2-ee45146add1e"}'

Мне нужно было преобразовать указанную выше строку Unicode в словарь Python. Итак, я делаю это:

try:
    body_dic = json.loads(item.get('body'))
    body_string = ""

    for body_item in body_dic.keys():
        body_string += body_item + ": {'required': True, 'type': 'resource', 'value': " + str(body_dic.get('body_item')) + "\n\t\t\t\t"

except Exception as e:
    print "futt gayaa"
    print type(e).__name__
    print e.args
    body_string = item.get('body')

а затем куча кода после этого. Таким образом, в приведенном выше моменте item.get('body') оказывается "1211V1", должно быть возбуждено ValueError Exception и поток выполнения должен попасть в блок except. Я прав ?

Однако он не поднимается, и поток выполнения продолжает переходить на следующую строку:

for body_item in body_dic.keys():

а затем возникает следующее исключение:

AttributeError ("у объекта 'unicode' нет атрибута 'ключи'",)

который я узнаю, если я изменю блок except выше, чтобы поймать общее исключение как:

except Exception as e:
    print "futt gayaa"
    print type(e).__name__
    print e.args
    body_string = item.get('body')

Пожалуйста, помогите мне понять это. На мой взгляд, в тот момент, когда возникает первое исключение (которое в нашем случае должно быть ValueError Exception), поток управления должен перейти в блок catch. Почему он переходит к следующей строке кода, а затем, когда возникает Исключение атрибута, он перехватывается.


person qre0ct    schedule 23.10.2017    source источник
comment
Предоставьте минимально воспроизводимый пример, демонстрирующий ошибку.   -  person Kevin    schedule 23.10.2017
comment
вы, вероятно, сериализовали строку, а не диктовку. Итак, json.loads возвращает строку   -  person Jean-François Fabre    schedule 23.10.2017


Ответы (2)


Предположим, что, как вы написали

print item.get("body")

возвращается буквально

"1211V1"

тогда кавычки являются частью самой строки.

Таким образом, вы эффективно звоните

json.loads('"1211V1"')

где вы загружаете строковый литерал JSON - совершенно верно. Затем, конечно, вы получаете AttributeError за попытку вызвать .keys() для объекта unicode.

Если вы используете print для отладки проблемы, это может ввести вас в заблуждение таким образом - вам лучше часто, если вы действительно хотите быть уверенным, с каким объектом у вас возникли проблемы, написать print(repr(obj)). В этом случае это говорит вам, что item.get("body") равно u'"1211V1"'.

person Iguananaut    schedule 23.10.2017
comment
Я также немного обеспокоен тем, что вы, кажется, пытаетесь создать какую-то строку JSON вручную с конкатенацией строк. Я не буду спрашивать почему, но могу поспорить, что вы идете по ложному пути без веской причины... - person Iguananaut; 23.10.2017
comment
Спасибо @Iguananaut. Совершенно разумно. Что касается подхода, почему я пытаюсь создать какую-то строку JSON вручную, короче говоря, существует устаревший инструмент, который ожидает данные в определенном формате. Нам нужно расширить код. (Пожалуйста, не спрашивайте, почему рефакторинг сейчас невозможен :D ) Отсюда весь этот цирк со строками и JSON. - person qre0ct; 23.10.2017
comment
@qre0ct, вы все равно можете собрать его с модулем json и не добавлять strs, json.dumps() - person Adirio; 23.10.2017

Итак, ваша проблема в том, что у вас есть последовательность диктов, тело атрибута которой представляет собой строку JSON. Это может быть:

"1211V1"

or:

{
    "points_token_id":"327727a0-3909-4132-8fa2-ee45146add1e"
}

Это строка JSON или объект JSON. Выполняя эту строку json.loads(), вы всегда получаете действительное значение Python, либо Python str, либо Python dict соответственно. Что вы хотите сделать, так это определить, является ли это тем или иным:

json_body = json.loads(item['body'])
if type(json_body) is dict:
    for key, value in json_body.items():
        json_body[key] = {'required': True, 'type': 'resource', 'value': value}
    body_string = json.dumps(json_body)
else:
    pass # Handle the "1211V1"
person Adirio    schedule 23.10.2017