Задача обработка ошибок на питоне

Рейтинг: -2Ответов: 6Опубликовано: 25.05.2023

Прохожу Пайтон, задали задачу на обработку ошибок. Не могу сообразить, как написать код.

Создайте функцию image_info с 1 параметром типа dict. Функция ожидает словарь, в к-ом должно быть как минимум 2 ключа: image_id, image_title. Функция должна возвращать строку такого вида: "image 'my cat' has id 5136" (my cat и id будут зависеть от ключей). Если хотя бы одного из этих ключей в словаре нет, функция должна генерировать ошибку TypeError. Вызовите функцию и корректно обработайте ошибку в случае возникновения.

Мой код:

def fn(image_info: dict):
     try:
        title = image_info['image_title']
        image_id = image_info['image_id']
     except KeyError:
        return "Image'my cat' has id 5136"
     return f'image {title} has id {image_id}'

Ответы

▲ 2
def fn(image_info: dict):
    try:
        return f"Image '{image_info['image_title']}' has id {image_info['image_id']}"
    except KeyError as e:
        raise TypeError(e)

try:
    s = fn({'': 'my cat', 'image_id': 5136})
except TypeError as e:
    print(e.__class__.__name__, e.__doc__, e.args)
    s = fn({'image_title': 'my cat', 'image_id': 5136})
print(s)
▲ 2
def image_info(info: dict):
    try:
        return f"image '{info['image_title']}' has id {info['image_id']}"
    except KeyError as e:
        raise TypeError from None  # генерируем *только* TypeError

print(image_info({'image_title': 'my cat', 'image_id': '5136'}))
print(image_info({}))

Без конструкции from None в строке

        raise TypeError from None
        #               ^^^^^^^^^

выполнение программы выглядело бы так:

image 'my cat' has id 5136  # Всё OK
Traceback (most recent call last):
  ...
KeyError: 'image_title'  # Сначала вызывается KeyError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  ...
TypeError  # А затем TypeError

А с ней вызывается только TypeError:

image 'my cat' has id 5136
Traceback (most recent call last):
  ...
TypeError  # Только TypeError
▲ 0
def function(foo):
    print(foo)

def fn(image_info: dict):
    try:
        return f"{'Image'} {image_info ['image_title']} {'has id'} {image_info ['image_id']}"
    except Exception as e:
        raise TypeError(f"{'not key'} {e}")

dict_win = {
    'image_title': 'my cat',
    'image_id': 5136
}

dict_one = {
    'image_title': 'my cat',
}

dict_two = {
    'image_id': 5136
}

try:
    print(fn(dict_win))
except TypeError as w:
    print(w)
▲ 0

Не пользуясь отловом exception в функции. Как то так можно получить конкретные ключи которые отсутствуют.

req_keys = ['image_title', 'image_id']

def fn(image_info: dict):
    if all(rq_check_list:=[key in req_keys for key in image_info.keys()]):
        return f"Image '{image_info['image_title']}' has id {image_info['image_id']}"
    else:
        raise TypeError(f"rq key/keys {[req_keys[idx] for idx, item in enumerate(rq_check_list) if item]} does not exist..")

try:
    s = fn({'': 'my cat', 'image_id': 5136})
except TypeError as e:
    print(e)
    

Вывод в случае отсутствия.

rq key/keys ['image_id'] does not exist..

Обратите внимание, что вызов exception под неподходящий тип ошибки - негативно сказывается на семантике и общей читабельности кода. Пишите семантически правильно. Нужно проверить ключи в какой либо структуре отличной от стандартных(и если идёте через путь exception) - рейзите обычный KeyError. Не стоит вписывать в exception's свои понятия.

В тривиальных случаях совершайте перехваты встроенными.

▲ 0
def image_info(info_dict):
    try:
        
        if 'image_id' not in info_dict or 'image_title' not in info_dict:
            raise KeyError("The dictionary must contain 'image_id' and 'image_title' keys.")

        
        result_str = f"image '{info_dict['image_title']}' has id {info_dict['image_id']}"
        return result_str
    except KeyError as e:
        
        raise TypeError(f"Error: {e}")



try:
  
    info_dict_1 = {'image_id': 5136, 'image_title': 'my cat'}

   
    result = image_info(info_dict_1)
    print(result)
except TypeError as e:
    
    print(f"Caught TypeError: {e}")
except Exception as ex_1:
  
    print(f"Caught Exception: {ex_1}")

try:
    
    info_dict_222 = {'image_id': 5136}


    result_33 = image_info(info_dict_222)
    print(result_33)
except TypeError as f:
    
    print(f"Caught TypeError: {f}")
except Exception as d:
   
    print(f"Caught Exception: {d}")
▲ 0
def image_info(image_dict):
    if 'image_id' not in image_dict:
        raise TypeError("Missing key 'image_id'")
    if 'image_title' not in image_dict:
        raise TypeError("Missing key 'image_title'")
    return print(f"Image {image_dict['image_title']} has id {image_dict['image_id']} !")


random_dict = {'image_title': 'my cat', 'image_id': 4411}

try:
    image_info(random_dict)
except Exception as e:
    print(e)