views:

220

answers:

4

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.

+4  A: 
if a is True:
    print 1

with statement is intended to provide a reliable enter-exit context.

SilentGhost
I was asking whether you can make a car can run on coca cola, and you answered "you should use fuel" :)like i said, i know this is feature-abusing, but consider it a programming riddle - is it possible?
noam
+2  A: 

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.

Rafał Dowgird
+7  A: 

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.

abyx
-1: `if a == True`. Please just say `if a`.
S.Lott
@S.Lott: No reason to downvote the answer because it does exactly what the question requires. It is the question that says "only if `a==True`".
Rafał Dowgird
-1: S.Lott is totally right, this is horrible style.
nikow
At least make it `a is True`.
nikow
`a is True` is *both* ugly and semantically different from `a==True` :)
Rafał Dowgird
Goddamit, I just copied what he said his condition should be.
abyx
How does copying it from the question make it any better? People see it and copy the code. Using `== True` is an antipattern in Python.
nikow
@Rafaek: `is True` is already much better than `== True`, and the only difference is that `is` is more efficient and better captures what you want to express.
nikow
@nikow: No, it is not the only difference. `1 == True` but `1 is not True`. Same goes for `1.0` (which is not 1.)
Rafał Dowgird
@Rafel: Sorry, you are right, I didn't think about that when I answered. I retracted my downvote. But while `a == True` should not be used `a is True` is legitimate (even though it is not the typical use case). Sorry again.
nikow
A: 

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.

ikkebr
This doesn't work for any value other than 1 that's passed to `A`: Traceback (most recent call last): File "<pyshell#9>", line 1, in <module> with b(A(2)): AttributeError: 'NoneType' object has no attribute '__exit__' That's because the `pass` in `b` doesn't return a valid context manager.
abyx
sure, it throws an AttributeError if the condition fails as stated :)
ikkebr
You stated it fails if the arguments doesn't have a `b` attribute, but even if it does, it will fail, if `c.b != 1`
abyx