Мне нужна помощь в понимании и использовании кортежа и создании пользовательских исключений - PullRequest
0 голосов
/ 29 марта 2020

Этот скрипт имитирует заказы внутри пиццерии. Я пытаюсь создать два исключения. Тот, который предупреждает вас, когда количество сыра слишком много. Тот, который уведомляет вас, когда пиццы нет в меню.

Почему строка print(tmce, ':', tmce.cheese) печатает too much cheese : 110, если в инструкции raise TooMuchCheeseError(pizza, cheese,"too much cheese") я передаю 3 аргумента?

не должен ли он печатать ('margherita', 110, 'too much cheese') : 110?
Используя аргументы кортежа, подобные этому print (tmce.args, ':', tmce.cheese) Я получаю следующий вывод: ('too much cheese',) : 110. Разве кортеж не должен содержать три элемента?

Вот код:

class PizzaError(Exception):
    def __init__(self, pizza, message):  
        Exception.__init__(self, message)
        self.pizza = pizza

class TooMuchCheeseError(PizzaError): 
    def __init__(self, pizza, cheese, message):
        PizzaError.__init__(self, pizza, message)
        self.cheese = cheese

def makePizza(pizza, cheese):
    if pizza not in ['margherita', 'capricciosa', 'calzone']:
        raise PizzaError(pizza, "no such pizza on the menu")
    if cheese > 100:
        raise TooMuchCheeseError(pizza, cheese, "too much cheese")
    print("Pizza ready!")

for (pz, ch) in [('calzone', 0), ('margherita', 110), ('mafia', 20)]:
    try:
        makePizza(pz, ch)
    except TooMuchCheeseError as tmce:
        print(tmce, ':', tmce.cheese)
    except PizzaError as pe:
        print(pe, ':', pe.pizza)

Вывод:

Pizza ready!
too much cheese : 110
no such pizza on the menu : mafia

1 Ответ

0 голосов
/ 01 апреля 2020

Главное, что нужно понять, это то, что происходит, когда вы пытаетесь напечатать объект (любой, не просто исключение). В фоновом режиме происходит вызов метода __str__ этого объекта и выводится его возвращаемое значение.

В разделе Обработка исключений в документации, рядом с которой в конце указано:

Для удобства экземпляр исключения определяет __str__(), поэтому аргументы могут быть напечатаны напрямую, без ссылки на .args.

Упомянутые args переданы в исключение. То есть к Exception х __init__. В вашем случае это просто message in:

Exception.__init__(self, message)

Если вы хотите, чтобы выводилось больше аргументов, вам нужно передать их в Exception args. Например, если вы измените вышеприведенную строку на:

Exception.__init__(self, pizza, message)

В результате вы получите:

Pizza ready!
('margherita', 'too much cheese') : 110
('mafia', 'no such pizza on the menu') : mafia

В качестве альтернативы, вы можете просто переопределить метод __str__ для вашего исключения. Например, добавление этого к TooMuchCheeseError:

def __str__(self):
    return "Oh no! the pizza {} has too much cheese: {}".format(self.pizza, self.cheese)

теперь даст:

Pizza ready!
Oh no! the pizza margherita has too much cheese: 110 : 110
no such pizza on the menu : mafia

Наконец, тот факт, что вы передаете сообщение об ошибках, немного избыточен. Поскольку ваши исключения служат определенной цели c, сообщение может быть им присуще. Это позволяет вашей обработке быть более динамичной c. Например:

class PizzaError(Exception):
    def __init__(self, pizza):
        super().__init__()
        self.pizza = pizza

    def __str__(self):
        return "Oh no! There is not a pizza '{}' on the menu".format(self.pizza)

class TooMuchCheeseError(PizzaError):
    def __init__(self, pizza, cheese):
        PizzaError.__init__(self, pizza)
        self.cheese = cheese

    def __str__(self):
        return "Oh no! the pizza {} has too much cheese: {}".format(self.pizza, self.cheese)

def makePizza(pizza, cheese):
    if pizza not in ['margherita', 'capricciosa', 'calzone']:
        raise PizzaError(pizza)
    if cheese > 100:
        raise TooMuchCheeseError(pizza, cheese)
    print("Pizza ready!")

for (pz, ch) in [('calzone', 0), ('margherita', 110), ('mafia', 20)]:
    try:
        makePizza(pz, ch)
    except (TooMuchCheeseError, PizzaError) as pe:
        print(pe)

напечатает:

Pizza ready!
Oh no! the pizza margherita has too much cheese: 110
Oh no! There is not a pizza 'mafia' on the menu 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...