How can I conditionally execute code in a “with” block?
-
05-07-2019 - |
Question
I guess this is kinda abusing the feature, but I'm still curious whether it could be done - I want to do something like:
with conditional(a):
print 1
so that the print 1
part is executed only if a==True.
Is this possible?
EDIT: Like people state below, this is horrible style. It's just a riddle\question. Don't try this at home, not for the faint of heart etc.
Solution
There's no real reason to do that, since conditionals are already supplied using the if
statement:
if a == True:
print 1
But, if you're just asking for fun, the answer is you can't really. To stop the with
content from executing, conditional
will need to somehow stop execution, in its __enter__
method. But the only way it can do that is raising an exception, which means no other code will run, unless you wrap the with
with a try
statement for handling cases a != True
Edit: seeing I was prosecuted in the comments and votes for using the OP's condition (a == True
) I considered changing it to if a
, which is of course the idiom in Python for testing conditionals. But, we do not know what the OP had in mind, and whether he really does want a
to be a boolean, and doesn't want block to execute if a = [1]
(which will pass if a
) I decided to leave it as is.
OTHER TIPS
if a is True:
print 1
with
statement is intended to provide a reliable enter-exit context.
The only way I see is to raise an exception in conditional
if its argument is false. The with
body will not be executed, but neither will any of the code that follows - until an except
or finally
clause, of course.
Let's say I have class A with an __enter__ and an __exit__ function:
class A:
def __init__(self, i):
self.b = i
def __exit__(*args, **kwargs):
print "exit"
def __enter__(*args, **kwargs):
print "enter"
And a function B that will check if b in object c equals 1 else it will pass.
def b(c):
if c.b == 1:
return c
else:
pass
I can achieve:
with b(A(1)):
print 10
enter
10
exit
But it will throw an AttributeError if b passes as the with won't have anything to work with.
A solution would be to put the with b(A(1)):
inside a try/except block. But I don't recommend doing this.