#python #transactions #return #try-catch
#python #транзакции #Возврат #попробуйте-поймайте
Вопрос:
Я расследую проблему, которую я сузил до одного места внутри метода следующего формата:
def method_shorthand(properties):
some stuff
some more stuff
return transaction.on_commit(
lambda: external_function_call_I_do_not_control(properties))
)
Для конкретного проблемного случая я могу воспроизвести, что external_function_call_I_do_not_control
(запуск события сегмента) не происходит / не выполняется успешно, хотя я определил, что вся информация верна вплоть до этого момента. Для этой кодовой базы ‘ATOMIC_REQUESTS’: True, поэтому я предсказываю либо:
- фиксация на самом деле не происходит (кажется маловероятным; эта функция вызывается как самый последний шаг успешного до этого блока кода)
- происходит фиксация или нет активной транзакции (в этом случае это просто выполняется), но когда происходит вызов этой функции, это каким-то образом вызывает рвоту — мои деньги на этом
Итак, я хотел бы добавить какой-нибудь блок try / catch в строку этой внешней функции, чтобы, если при ее выполнении возникнет исключение, я мог перехватить это, записать информацию и посмотреть, в чем дело, чтобы я мог это исправить. Проблема в том, что все это находится внутри return transaction.on_commit, поэтому все, что я пробую, кажется неправильным синтаксисом, и, оглядываясь вокруг, я не смог найти пример выполнения этого.
Есть ли безопасный способ добавить блок try / catch внутри этой возвращаемой транзакции.on_commit? Любые другие идеи по устранению неполадок, поскольку фактический вызов функции является внешним, и я не могу изменить код для ведения журнала / отладки?
Ответ №1:
Вместо использования лямбда-выражения используйте целую функцию, которая позволяет выполнять более сложные действия, чем лямбда-выражение (которое обычно представляет собой просто прямую карту ввода -> вывода).
def method_shorthand(properties):
some stuff
some more stuff
def oncommit():
try:
external_function_call_I_do_not_control(properties)
except Exception as e:
# do whatever error handling needs to be done
return transaction.on_commit(oncommit)
Комментарии:
1. Ах, это выглядит как хороший способ разобраться с этим — попробую ответить — спасибо!!!
2. это было очень полезно! Я могу сделать это, как я надеялся, НО эта лямбда была добавлена намеренно прошлой осенью, поэтому я думаю, что это необходимо там (и все виды тестов терпят неудачу, когда я ее удаляю). Похоже, что лямбда используется, когда нам нужно передать функцию (а не результат функции), поэтому мне интересно, смогу ли я выяснить, где / когда она, наконец, выполняется, и добавить свою попытку / except туда вместо этого? Похоже, сегодняшней задачей будет больше узнать о lambda….
3. Как только они были созданы, нет разницы между лямбда-выражением и функцией. Они неразличимы. Единственное отличие заключается в том, что лямбда-выражение может быть записано встроенным и является простым вводом / выводом. Обратите внимание, как
transaction.on_commit
передаетсяoncommit
, неoncommit()
— он передает функцию без ее вызова, что аналогично тому, что было бы сделано с лямбда.4. Я не заметил этого различия — интересно. Я старался держаться как можно ближе к исходному коду (который включает «(свойства)», поэтому я предполагаю, что это выполняет вызов функции) — и просто добавить дополнительную обработку. Необычно ли, что в исходном коде есть лямбда-функция, в которой она действительно выполняет вызов, а не просто передает имя функции?
5. @DianeKaplan Причина, по которой в исходном коде есть лямбда, вероятно, в том, что
transaction.on_commit()
требуется функция с 0 аргументами, ноexternal_function...()
требуется один аргумент. Лямбда-выражение служит посредником, который позволяет вам эффективно превратить функцию с одним аргументом в функцию с нулевым аргументом (поскольку, в конце концов, на момент ее объявления вы уже знаете, что такоеproperties
, поэтому оно с таким же успехом может быть константой).