Какая лучшая практика в пользовательской функции в Python: raise
исключение или return None
? Например, у меня есть функция, которая находит самый последний файл в папке.
def latestpdf(folder):
# list the files and sort them
try:
latest = files[-1]
except IndexError:
# Folder is empty.
return None # One possibility
raise FileNotFoundError() # Alternative
else:
return somefunc(latest) # In my case, somefunc parses the filename
Другой вариант - оставить исключение и обработать его в коде вызывающего абонента, но я считаю, что проще иметь дело с a, FileNotFoundError
чем с файлом IndexError
. Или это дурной тон - повторно вызывать исключение с другим именем?
python
exception-handling
паркидарк
источник
источник
Ответы:
Это действительно вопрос семантики. Что
foo = latestpdf(d)
значит ?Совершенно разумно, что нет последнего файла? Тогда конечно, просто верните None.
Вы ожидаете, что всегда найдете последний файл? Поднимите исключение. И да, можно повторно поднять более подходящее исключение.
Если это просто общая функция, которая должна применяться к любому каталогу, я бы сделал первое и вернул None. Если каталог, например, предназначен для того, чтобы быть конкретным каталогом данных, который содержит известный набор файлов приложения, я бы вызвал исключение.
источник
None
.Я хотел бы сделать пару предложений, прежде чем отвечать на ваш вопрос, поскольку он может ответить на ваш вопрос.
latestpdf
мало что значит для кого-то, но просмотр вашей функцииlatestpdf()
получает последний PDF-файл. Я предлагаю вам назвать этоgetLatestPdfFromFolder(folder)
.Как только я это сделал, стало ясно, что он должен возвращать .. Если нет pdf - возбуждает исключение. Но подожди еще ..
for folder in folders: try: latest = getLatestPdfFromFolder(folder) results = somefuc(latest) except IOError: pass
Надеюсь это поможет!
источник
get_latest_pdf_from_folder
. Действительно, Pep8: «Имена функций должны быть в нижнем регистре, а слова должны быть разделены подчеркиванием по мере необходимости для улучшения читаемости».Я обычно предпочитаю обрабатывать исключения внутренне (например, try / except внутри вызываемой функции, возможно, возвращая None), потому что python динамически типизирован. В общем, я так или иначе считаю это суждением, но в динамически типизированном языке есть небольшие факторы, которые склоняют чашу весов в пользу отказа от передачи исключения вызывающей стороне:
if val is None
немного проще, чемexcept ComplicatedCustomExceptionThatHadToBeImportedFromSomeNameSpace
. Серьезно, я ненавижу не забывать вводитьfrom django.core.exceptions import ObjectDoesNotExist
текст в верхней части всех моих файлов django, чтобы справиться с действительно распространенным вариантом использования. В мире со статической типизацией позвольте редактору сделать это за вас.Однако, честно говоря, это всегда суждение, и описываемая вами ситуация, когда вызываемая функция получает ошибку, которую она не может помочь, является отличной причиной для повторного создания значимого исключения. У вас есть точная правильная идея, но, если вы не исключение, предоставит более значимую информацию в трассировке стека, чем
AttributeError: 'NoneType' object has no attribute 'foo'
что в девяти случаях из десяти - это то, что абонент увидит, если вы вернете необработанное None, не беспокойтесь.
(Все это заставляет меня желать, чтобы исключения python имели
cause
атрибуты по умолчанию, как в java, что позволяет передавать исключения в новые исключения, чтобы вы могли повторно выбросить все, что захотите, и никогда не терять исходный источник проблемы.)источник
с Python 3.5 в типизации :
Пример функции при возврате None будет:
def latestpdf(folder: str) -> Union[str, None]
и при возникновении исключения будет:
def latestpdf(folder: str) -> str
вариант 2 кажется более читаемым и питоническим
(+ возможность добавить комментарий к исключению, как указано ранее.)
источник
Union[str, None]
должно бытьOptional[str]
В общем, я бы сказал, что должно быть выбрано исключение, если произошло что-то катастрофическое, что не может быть восстановлено (т.е. ваша функция имеет дело с каким-то интернет-ресурсом, к которому невозможно подключиться), и вы должны вернуть None, если ваша функция действительно должна что-то возвращать. но ничего не следует возвращать (например, «Нет», если ваша функция пытается сопоставить подстроку в строке).
источник