I am defining a context manager class and I would like to be able to skip the block of code without raising an exception if certain conditions are met during instantiation. For example,
class My_Context(object):
def __init__(self,mode=0):
"""
if mode = 0, proceed as normal
if mode = 1, do not execute block
"""
self.mode=mode
def __enter__(self):
if self.mode==1:
print 'Exiting...'
CODE TO EXIT PREMATURELY
def __exit__(self, type, value, traceback):
print 'Exiting...'
with My_Context(mode=1):
print 'Executing block of codes...'
What you're trying to do isn't possible, unfortunately. If
__enter__
raises an exception, that exception is raised at thewith
statement (__exit__
isn't called). If it doesn't raise an exception, then the return value is fed to the block and the block executes.Closest thing I could think of is a flag checked explicitly by the block:
This also lets you raise
Break()
in the middle of awith
block to simulate a normalbreak
statement.According to PEP-343, a
with
statement translates from:to:
As you can see, there is nothing obvious you can do from the call to the
__enter__()
method of the context manager that can skip the body ("BLOCK
") of the with statement.People have done Python-implementation-specific things, such as manipulating the call stack inside of the
__enter__()
, in projects such as withhacks. I recall Alex Martelli posting a very interesting with-hack on stackoverflow a year or two back (don't recall enough of the post off-hand to search and find it).But the simple answer to your question / problem is that you cannot do what you're asking, skipping the body of the with statement, without resorting to so-called "deep magic" (which is not necessarily portable between python implementations). With deep magic, you might be able to do it, but I recommend only doing such things as an exercise in seeing how it might be done, never in "production code".
If you want an ad-hoc solution that uses the ideas from withhacks (specifically from AnonymousBlocksInPython), this will work:
Compare the following:
with
A python 3 update to the hack mentioned by other answers from withhacks (specifically from AnonymousBlocksInPython):
As mentioned before by joe, this is a hack that should be avoided: