Переменная не присвоена в блоке except

Вопрос или проблема

Блок try-except-finally не присваивает переменной значение в блоке except:

 if "access_token" in result.keys():
        print("Успешное получение токена из:", result["token_source"])  # Начиная с MSAL 1.25
        # Вызов веб-API с использованием токена доступа
        r = requests.get(
            queryURL,
            headers={'Authorization': 'Bearer ' + result['access_token'], 'Prefer':'odata.include-annotations="OData.Community.Display.V1.FormattedValue"'},
            )
        t = r.text
        api_result = r.json()
        try:
            query = api_result['value']
        except KeyError:
(ЭТА СТРОКА) query = api_result
            if 'error' in api_result:
                err_code, err_msg = api_result['error'].items()
                raise DataverseError(err_code, err_msg)
            raise NoValuesBlockError(api_result.keys())
        finally:
            return query
else:
        raise TokenAcquisitionError(value=result)
api_result.keys() = 
dict_keys(['@odata.context', '@odata.type', 'ParentOptionSetName', 'IsCustomOptionSet',
'IsGlobal', 'IsManaged', 'Name', 'ExternalTypeName', 'OptionSetType', 'IntroducedVersion', 
'MetadataId', 'HasChanged', 'Options', 'Description', 'DisplayName', 'IsCustomizable'])

но query не присвоен api_result в выделенной строке.

Существует случай, когда нет блока значений и нет блока ошибок, который должен быть перехвачен и все равно возвращен.

def test():
    keys = ['@odata.context', '@odata.type', 'ParentOptionSetName', 'IsCustomOptionSet','IsGlobal', 'IsManaged', 'Name', 'ExternalTypeName', 'OptionSetType', 'IntroducedVersion', 'MetadataId', 'HasChanged', 'Options', 'Description', 'DisplayName', 'IsCustomizable',"access_token"]
    result ={key: None for key in keys}
    result["token_source"] = "test"
    if "access_token" in result.keys():
        print("Успешное получение токена из:", result["token_source"])  # Начиная с MSAL 1.25
        # Вызов веб-API с использованием токена доступа
        api_result = {"testKey":"testValue"}
        try:
            query = api_result['value']
        except KeyError:
            query = api_result
            if 'error' in api_result:
                err_code, err_msg = api_result['error'].items()
                raise Exception(err_code, err_msg)
            raise Exception(api_result.keys())
        finally:
            return query
    else:
        raise Exception(value=result)

print(test())

# результат: 
# Успешное получение токена из: test
# {'testKey': 'testValue'}
  • так как ваш вопрос неясен без отладочной информации и стека ошибок, я предполагаю, что возможная причина ошибки заключается в том, что в ваших api_result.keys() нет "access_token", поэтому программа просто переходит к строке TokenAcquisitionError(value=result) без какого-либо возвращаемого значения, и вы думаете, что “query не присвоен api_result в выделенной строке”

Ответ или решение

Ваша проблема заключается в том, что переменная query не всегда будет присвоена значению внутри блока except, если определенные условия не выполнены. Рассмотрим ваш код более детально и разберем, как можно улучшить его обработку исключений и возвращаемые значения.

Ваша текущая реализация предполагает, что если api_result не содержит ключ 'value', программа переходит к присвоению query значению api_result. Однако, если в api_result нет ни «значений», ни «ошибок», код просто завершает выполнение без возврата значения query, что и вызывает ваше замешательство.

Вот как можно переписать ваш код, чтобы обработать все случаи:

def test():
    keys = ['@odata.context', '@odata.type', 'ParentOptionSetName', 'IsCustomOptionSet',
            'IsGlobal', 'IsManaged', 'Name', 'ExternalTypeName', 'OptionSetType',
            'IntroducedVersion', 'MetadataId', 'HasChanged', 'Options', 'Description',
            'DisplayName', 'IsCustomizable', "access_token"]

    result = {key: None for key in keys}
    result["token_source"] = "test"

    if "access_token" in result.keys():
        print("Успешное получение токена из:", result["token_source"])  # С MSAL 1.25
        # Вызов веб-API с использованием токена доступа
        api_result = {"testKey": "testValue"}  # Это временный результат для тестирования

        try:
            query = api_result['value']
        except KeyError:
            query = api_result  # Если 'value' нет, сохраняем api_result в query
            if 'error' in api_result:
                err_code, err_msg = api_result['error'].items()
                raise Exception(err_code, err_msg)  # Генерируем ошибку
            # Новая проверка: если query все равно не был задан
            if not query:
                raise Exception("Нет значений и нет ошибок в api_result. Вернул: {}".format(api_result))

        # Здесь можно добавить обрабатываемую логику по query, если нужно
        return query
    else:
        raise Exception(value=result)

print(test())  # Запуск функции

Объяснение изменений:

  1. Обработка отсутствия значений: Мы добавили дополнительную проверку на случай, если ни value, ни error присутствуют в api_result. Это обеспечивает возврат информативной ошибки.
  2. Согласно вашим требованиям: Всегда возвращается переменная query, даже если она будет содержать api_result, когда value не найден.

Теперь, если в api_result не будет задано значение ключа value, но не будет и ошибок, вы получите четкую ошибку, указывающую на проблему, что поможет вам диагностировать код.

Оцените материал
Добавить комментарий

Капча загружается...