Python: try-except как выражение?

Я снова и снова сталкиваюсь с подобным узором:

variable = "" try: variable = ... do some file loading stuff ... except: variable = "" 

Есть ли способ сконденсировать это в одно выражение? Как и с операторами if-else, вы можете включить:

 variable = "" if something: variable = somethingelse else: variable = "" 

в

 variable = somethingelse if something else "" 

Есть ли какая-то эквивалентная вещь для попытки?

6 Solutions collect form web for “Python: try-except как выражение?”

Поскольку agf уже предоставил подход, который я бы рекомендовал, вот версия его рутины с несколькими незначительными улучшениями:

 def try_except(success, failure, *exceptions): try: return success() except exceptions or Exception: return failure() if callable(failure) else failure 

Эта версия:

  1. Позволяет точно указать, какие исключения будут пойманы как дополнительные необязательные аргументы. Вы всегда должны улавливать минимальный набор исключений, которые будут выполнять задание, и разрешить исключения, с которыми вы не можете обработать пузырь до вызывающего.

  2. Поддерживает использование простого значения, а также функцию для значения отказа. Это избавит вас от необходимости использовать лямбда во многих случаях. (Конечно, вместо lambda: '' вы можете просто использовать str .)

 def try_except(success, failure): try: return success() except: return failure() variable = try_except(do_some_file_loading_stuff, lambda: '') 

Я думаю, что код сам объясняет. Он возвращает значение, возвращенное success если нет ошибки, затем возвращается значение, возвращаемое failure . Если do_some_file_loading_stuff является выражением, а не просто вызовом функции, оберните его также в lambda .

Edit: @kindall, и я немного ударил его версию, так что он так же быстро, как и мой, можно назвать точно так же, если хотите, имеет больше возможностей и имеет такое же количество строк. Используй это!

 def try_except(success, failure, *exceptions): try: return success() except exceptions or Exception: return failure() if callable(failure) else failure 

Вот менеджер контекста, который предоставляет немного ярлыка:

 from contextlib import contextmanager @contextmanager def catch(*exceptions, **kwargs): try: yield kwargs.get("default", None) except exceptions or Exception: pass 

Применение:

 with catch(ZeroDivisionError, default=0) as x: x = 3 / 0 # error print x # prints 0, the default 

Основная идея здесь заключается в том, что диспетчер контекста возвращает любое значение по умолчанию, которое вы передаете ему, которое затем присваивается переменной, указанной в предложении as . Затем внутри контекста вы выполняете оператор, который пытается назначить эту же переменную. Если он вызывает исключение, менеджер контекста ловит и молча игнорирует его, но поскольку присваивание не произошло, значение по умолчанию остается.

Может быть особенно полезно для многострочных вычислений, которые, тем не менее, приводят к одному значению.

К сожалению, нет, для него нет языковой конструкции, и я тоже не знаю какой-либо четкой и лаконичной идиомы. Я всегда хотел чего-то подобного. Некоторое время назад кто-то дал мне основания для того, чтобы Python не имел что-то вроде variable = function_cal() except "" но они были не очень убедительными, и я все еще пропущу эту языковую конструкцию 🙂

Очевидно, что последний способ сделать это более кратким и предпочтительнее многих программистов, подобных вам.

Хотя сам язык не обеспечивает «однострочный try-except-catch» по каким-либо причинам, все хорошее и необходимое, я полагаю, вы можете в целом выполнить это, немного изменив программу; как например:

 try: a_var = a_dict.get('abcd') except a_dict.KeyError: a_var = '' 

в:

 a_var = a_dict.get('abcd',default='') 

и аналогично для запросов БД;

 try: a_qs = Model.objects.get(id=42) except Model.DoesNotExist: a_qs = Model.objects.create(id=42) 

с

 a_qs = Model.objects.get_or_create(id=42,**kwargs) 

и добавьте аналогичные API в свои собственные программы, где это возможно. try-except довольно «дешево» в Python, и программирование на основе исключения предпочтительнее, чем подход «check-first», обычно предлагаемый на Java, например, языки из-за дорогостоящего характера обработки исключений. Таким образом, вы должны скорее обернуть эту «захватывающую вещь» в методе / функции и вызвать ее, где угодно, например, в случае с dict и другими конструкциями.

Нет простого способа упростить оператор try / catch, такой как пример if / else, но я хочу указать, что оператор python с инструкцией, представленный в python2.5, сделал много интерфейсов для файлов / db io try catch statement simpleer и безопасным исключением. Операции ввода-вывода, как правило, используются там, где используется множество инструкций try / catch.

 with open("myfile.txt", "r") as f: # Do stuff with f 

вместо

 try: f = open("myfile.txt", "r") # Do stuff with f except: pass finally: if f: f.close 
  • Скопируйте файл или каталоги рекурсивно в Python
  • Список только файлов в каталоге?
  • Измените файл DBF
  • Это приложение не существует (app_id = xxx)
  • Python: понимание составления двух словарей
  • RuntimeError: ошибка autoconf при установке google-endpoints
  • Библиотека Python для разбора файлов, разделенных пробелами
  • Pyparsing: получить расположение маркера в имени результатов
  • Python - лучший язык программирования в мире.