Вопрос или проблема
Блок 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
в выделенной строке.
Существует случай, когда нет блока значений и нет блока ошибок, который должен быть перехвачен и все равно возвращен.
- ваш код не является минимальным воспроизводимым примером (https://stackoverflow.com/help/minimal-reproducible-example), я немного изменил его на следующий код:
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()) # Запуск функции
Объяснение изменений:
- Обработка отсутствия значений: Мы добавили дополнительную проверку на случай, если ни
value
, ниerror
присутствуют вapi_result
. Это обеспечивает возврат информативной ошибки. - Согласно вашим требованиям: Всегда возвращается переменная
query
, даже если она будет содержатьapi_result
, когдаvalue
не найден.
Теперь, если в api_result
не будет задано значение ключа value
, но не будет и ошибок, вы получите четкую ошибку, указывающую на проблему, что поможет вам диагностировать код.