Предположим, у меня есть какой-то контекстный менеджер (из сторонней библиотеки), который я использую так:
with freeze_time(test_dt):
lines_of_code_1
lines_of_code_2
lines_of_code_3
Но предположим, что если для test_dt нет значения, менеджер контекста не должен запускаться, но весь оставшийся код должен выполняться, например:
if test_dt:
with freeze_time(test_dt):
lines_of_code_1
lines_of_code_2
lines_of_code_3
else:
lines_of_code_1
lines_of_code_2
lines_of_code_3
Предположим, что lines_of_code
здесь 2-3 строки кода, которые абсолютно идентичны, есть ли более чистый способ написать это? Я знаю, что мог бы написать что-то вроде этого:
def do_thing():
lines_of_code_1
lines_of_code_2
lines_of_code_3
if test_dt:
with freeze_time(test_dt):
do_thing()
else:
do_thing()
Но я не без ума от этого форматирования. Кроме того, я не хочу засорять этот шаблон по всему коду.
Есть еще одна последняя возможность, но я не уверен, что она сработает: создание подкласса менеджера контекста и пропуск функций __enter__
и __exit__
, если заданный test_dt пуст, например:
class optional_freeze_time(object):
def __init__(self, test_dt=None):
if test_dt:
self.ctx_manager = freeze_time(test_dt)
else:
self.ctx_manager = None
def __enter__(self, *args, **kwargs):
if self.ctx_manager:
self.ctx_manager.__enter__(*args, **kwargs)
def __exit__(self, *args, **kwargs):
if self.ctx_manager:
self.ctx_manager.__exit__(*args, **kwargs)
Я протестировал его с пустым классом менеджера контекста, и он, похоже, работал корректно. Однако меня беспокоит, правильно ли будет вести себя настоящий менеджер контекста, если я это сделаю (я не очень хорошо знаком с внутренностями того, как он работает).
if input is None:
. Вы проверяли то, что написали? - person jonrsharpe   schedule 21.12.2016blank_context_manager
, который ничего не делает, и переопределитьcontext_manager.__new__
, чтобы вернуть пустой, если нет ввода, уменьшит количество условных выражений до 1. - person Tadhg McDonald-Jensen   schedule 21.12.2016