Найти - Пользователи
Полная версия: Поведение кастомных исключений
Начало » Python для новичков » Поведение кастомных исключений
1
missterr
Чем обусловленна необходимось импортирования кастомных исключений в пространство имен, где осуществляется их обработка?
пример:
exc.py
class IncorrectArg(Exception):
    def __str__(self):
        return "Error message", arrs 

lib.py
from exc import IncorrectArg #Без этого, конечно, экземпляр исключения не создать.
class foo(object):
    def __init__(self, arg1, arg2):
        if condition:
            raise IncorrectArg(arg1, arg2)
        else:
            do something

main.py
from lib import foo
from exc import IncorrectArg """По идее, интерпритатор можен вытолкнуть созданный объект исключения и присвоить его переменной err."""
    try:
        myObj = foo(arg1, arg2)
    except IncorrectArg as err:
        print(err)

Знатоки, кто может прокоментировать?
lorien
> Чем обусловленна необходимось импортирования кастомных исключений в пространство имен, где осуществляется их обработка?

Тем, что вы используете имя исключения, и интерпретатору надо знать, что это за имя. Любое имя в программе должно быть объявлено в текущем модуле: явно или с помощью импортирования.

За исключением встроенных функций и имён базовых типов.
fata1ex
Разумеется, можно наваять много магии, чтобы сэкономить несколько строк кода, но:
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.

missterr
Тем, что вы используете имя исключения, и интерпретатору надо знать, что это за имя. Любое имя в программе должно быть объявлено в текущем модуле: явно или с помощью импортирования.
Неубедительно. Как это работает - очевидно, неочевидно с какой целью, весь смысл исключений во “всплывании” его из глубин, так сказать)

Explicit is better than implicit.
С этой точки зрения логично.

Не эстетично получается. Скажем, разработал ты библиотечку для сторонних пользователей. Есть 2 варианта:
1. Либо забить на исключения и возвращать сигналы(0, -1 и т.п.)/строки(“Error was caught..”) при возникновении ожидаемых ошибок.
2. Либо заставлять пользователя везде импортировать кучу хлама…

По идее, можно ничего не импортировать и делать так:
try:
        myObj = foo(arg1, arg2)
    except Exception as err:
        print(err)

Но это не похоже на best practices.
fata1ex
missterr, внутренние исключения в библиотеке можно обрабатывать самостоятельно внутри, а пользователю выкидывать стандартные, вроде ValueError или TypeError. Если совсем специфичная вещь, для которой обязательно нужно своё исключение, пользователям будет несложно написать пару импортов. Как например: from django.http import Http404.
missterr
fata1ex, а если в моем коде действительно произойдет ValueError или TypeError, пользователь библиотеки обработает и выведет конечному пользователю, мол “Что-то ты делаешь не правильно дружок”… ошибка похоронена. Лучше уж заставить импортировать.

Да,
from django.http import Http404
это разработчики джанги красиво придумали, у меня не так специфично)
fata1ex
missterr, ну это аргумент из серии “если вдруг я ошибусь и всё испорчу” :) В нормальном оттестированном коде вероятность, что в том месте, где вы выкидываете исключение, которое ждёт пользователь библиотеки, действительно произойдёт это же самоё исключение, которого вовсе не ждёт пользователь библиотеки, куда ниже, чем вероятность, что просто что-нибудь пойдёт не так и сломается. Вот такое длинное предложение.
lorien
> 2. Либо заставлять пользователя везде импортировать кучу хлама…

Он будет импортировать классы исключений тоолько в том. случае, если будет хотеть их обрабатывать. Если пользователю нужно просто поймать любые исключения, он воспользуется except Exception конструкцией.

Кроме того, обычно все исключения библиотеки наследуются от какого-то общего исключения библиотеки, так чтобы пользователь мог ловить их с помощью одного класса. Например, у меня в Grab есть GrabError, а от него наследуются GrabNetworkError, GrabTimeoutError и т.д.
missterr
lorien, весьма показательный и авторитетный пример, благодарю.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB