Can I have a context manager which occasionally does not yield, and in which case the code within the with statement are simply not executed?
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 a try-catch, but that is not preferred. I could also do the following but it is ugly too.
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.'
yield expression returns control to the whatever is using the generator. The generator pauses at this point, which means that the @contextmanager decorator knows that the code is done with the setup part.
A context manager usually takes care of setting up some resource, e.g. opening a connection, and automatically handles the clean up when we are done with it. Probably, the most common use case is opening a file. The code above will open the file and will keep it open until we are out of the with statement.
Context managers can be written using classes or functions(with decorators). Creating a Context Manager: When creating context managers using classes, user need to ensure that the class has the methods: __enter__() and __exit__().
Another option would be to just use a regular generator rather than a contextmanager; a plain generator won't have this restriction. But you'll have to use it with a "for" construct rather than using "with":
def MayNotYield(to_yield):
if to_yield:
yield
for _ in MayNotYield(True):
print('This prints.')
for _ in MayNotYield(False):
print('This does not.')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With