Здравствуйте, Буравчик, Вы писали:
Да, это можно. Пришлось вспомнить как это работает-)))
Б>@contextmanager
def needRun():
try:
yield
except RuntimeError as e:
if e.args[0] != "generator didn't yield":
raise # Raising everything else
@contextmanager
def contextOnCondition(flag: bool=True):
if flag:
yield True
if __name__ == "__main__":
flag = True
with needRun(), contextOnCondition(flag):
print("It ran")
flag = False
with needRun(), contextOnCondition(flag):
print("It did not run")
Б>
Задача: написать контекстный менеджер need_run, который мог бы выполнять или не выполнять код в зависимости от заданного условия.
# код должен вывести только "must be printed"
with need_run(True):
print('must be printed')
with need_run(False):
print('must not be printed')
Возможно ли в принципе? Возможно ли решение без привязки к конкретной реализации?
σ>>https://pypi.org/project/conditional-context/?
Б>Примерно так я и представлял реализацию.
Б>Не ожидал, что даже готовый пакет есть
В гугле вообще много всего найти можно. Жаль, что Вас там забанили.
Здравствуйте, Буравчик, Вы писали:
Б>Задача: написать контекстный менеджер need_run, который мог бы выполнять или не выполнять код в зависимости от заданного условия.
Б>Возможно ли в принципе? Возможно ли решение без привязки к конкретной реализации?
Если и возможно, то как-то очень хитро. Доки говорят, что код
with EXPRESSION as TARGET:
SUITE
эквивалентен следующему:
manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
hit_except = False
try:
TARGET = value
SUITE
except:
hit_except = True
if not exit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
exit(manager, None, None, None)
То есть никаких зацепок для предотвращения запуска полезной нагрузки просто не предусмотрено. Можно швырнуть исключение в __enter__(), но тогда весь with упадёт.
Не исключаю, что существуют какие-то трюки с залезанием во всякие дебри, но тут у меня недостаточно знаний.
А из интереса, почему именно with? Чем if не устроил?
Здравствуйте, CaptainFlint, Вы писали:
CF>А из интереса, почему именно with? Чем if не устроил?
Нужен именно контекстный менеджер. И поэтому приходится писать:
with manager() as m:
if m.condition:
... code here ...
Здравствуйте, Буравчик, Вы писали:
Б>Нужен именно контекстный менеджер. И поэтому приходится писать:
Б>Б>with manager() as m:
Б> if m.condition:
Б> ... code here ...
Б>
Надо больше угара
class Manager:
def __init__(self):
self.active=True
self.last_fn=None
def need_run(self,fn,scope):
print("run",scope,self.active)
return self.active
def exec_with(manager,scope=""):
def decorator(fn):
manager.last_fn=fn
if manager.need_run(fn,scope): fn(manager)
return decorator
manager=Manager()
#---------------------------------------------------
@exec_with(manager,"main")
def body(m):
print("code here 1")
manager.active=False
@exec_with(manager,"optional")
def _(m):
print("code here 2")
Здравствуйте, Ватакуси, Вы писали:
В>Да, это можно. Пришлось вспомнить как это работает-)))
Хм, интересный подход
Здравствуйте, σ, Вы писали:
σ>https://pypi.org/project/conditional-context/?
Примерно так я и представлял реализацию.
Не ожидал, что даже готовый пакет есть