Context manager without exit

Can I have a context manager that sometimes fails, in which case the code inside the with statement just doesn't execute?

import contextlib

@contextlib.contextmanager
def MayNotYield(to_yield):
  if to_yield:
    yield

with MayNotYield(True):  
  print 'This works.'

with MayNotYield(False):  
  print 'This errors.'

I could ask the user to wrap the with statement with try-catch, but this is not preferred. I could also do the following, but it is also ugly.

import contextlib

@contextlib.contextmanager
def AlwaysYields(to_yield):
  if to_yield:
    yield 1
  else:
    yield 2

with AlwaysYields(True) as result:
  if result == 1:
    print 'This works.'
+7
source share
3 answers

, " with" ( __enter__). , , , __enter__ , , , . - , if:

if do_stuff:
    # do the stuff
+5

, , . do-nothing, , . - , .

def do_something():
    print("This works!")

@contextlib.contextmanager
def conditional_on(condition, f):
    if condition:
        # Acquire resources here
        pass
    else:
        # Replace the callable with a do-nothing dummy
        f = lambda x: x
    try:
        yield f
    finally:
        if condition:
            # Release resources here
            pass    

with conditional_on(True, do_something) as f:
    f()  # Prints message

with conditional_on(False, do_something) as f:
    f()  # Does nothing

, , , , .

0

- , ; . "for", "with":

def MayNotYield(to_yield):
   if to_yield:
      yield

for _ in MayNotYield(True):
   print('This prints.')

for _ in MayNotYield(False):
   print('This does not.')
0

Source: https://habr.com/ru/post/1622142/


All Articles