如何在“with”块中有条件地执行代码?

时间:2009-11-27 13:07:46

标签: python with-statement

我想这有点滥用这个功能,但我仍然很好奇是否可以这样做 - 我想做点什么:

with conditional(a):
    print 1

这样只有在== True时才会执行print 1部分。 这可能吗?

编辑: 就像下面的人一样,这是一种可怕的风格。这只是一个谜语\问题。不要在家里试试,不要为胆小的人等尝试。

4 个答案:

答案 0 :(得分:8)

没有真正的理由这样做,因为条件已经使用if语句提供:

if a == True:
    print 1

但是,如果你只是要求有趣,答案是你不能。要阻止with内容执行,conditional将需要以__enter__方法以某种方式停止执行。但它能做到这一点的唯一方法是引发异常,这意味着不会运行其他代码,除非你用with语句包裹try语句来处理案例a != True

编辑:看到我在评论和投票中被起诉使用OP的条件(a == True)我考虑将其更改为if a,这当然是成语在Python中用于测试条件。但是,我们不知道 OP的想法是什么,以及他是否确实希望a成为布尔值,并且如果a = [1]不希望执行块(将通过if a)我决定保留原样。

答案 1 :(得分:4)

if a is True:
    print 1

with statement旨在提供可靠的进入退出环境。

答案 2 :(得分:2)

我看到的唯一方法是在conditional中引发异常,如果它的参数为false。 with正文将不会被执行,但后面的任何代码都不会被执行 - 当然,直到exceptfinally子句。

答案 3 :(得分:0)

假设我有一个带有__enter__和__exit__函数的A类:

class A:
    def __init__(self, i):
        self.b = i
    def __exit__(*args, **kwargs):
        print "exit"
    def __enter__(*args, **kwargs):
        print "enter"

一个函数B将检查对象c中的b是否等于1,否则它将通过。

def b(c):
    if c.b == 1:
        return c
    else:
        pass

我可以实现:

with b(A(1)):
    print 10


enter
10
exit

但是如果b传递,它将抛出一个AttributeError,因为带的将无法使用。 解决方案是将with b(A(1)):置于try / except块中。但我不建议这样做。