Short-circuit evaluation like Python's "and" while storing results of checks
<p>I have multiple expensive functions that return results.  I want to return a tuple of the results of all the checks if all the checks succeed.  However, if one check fails I don't want to call the later checks, like the short-circuiting behavior of <code>and</code>.  I could nest <code>if</code> statements, but that will get out of hand if there are a lot of checks.  How can I get the short-circuit behavior of <code>and</code> while also storing the results for later use?</p>

<pre><code>def check_a():
    # do something and return the result,
    # for simplicity, just make it "A"
    return "A"

def check_b():
    # do something and return the result,
    # for simplicity, just make it "B"
    return "B"

...
</code></pre>

<p>This doesn't short-circuit:</p>

<pre><code>a = check_a()
b = check_b()
c = check_c()

if a and b and c:
    return a, b, c
</code></pre>

<p>This is messy if there are many checks:</p>

<pre><code>if a:
   b = check_b()

   if b:
      c = check_c()

      if c:
          return a, b, c
</code></pre>

<p>Is there a shorter way to do this?</p>

<p>Flexible short circuiting is really best done with Exceptions. For a very simple prototype you could even just assert each check result:</p>

<pre><code>try:
    a = check_a()
    assert a
    b = check_b()
    assert b
    c = check_c()
    assert c
    return  a, b, c
except AssertionException as e:
    return None
</code></pre>

<p>You should probably raise a custom Exception instead. You could change your check_X functions to raise Exceptions themself, in an arbitrary nested way. Or you could wrap or decorate your check_X functions to raise errors on falsy return values.</p>

<p>In short, exception handling is very flexible and exactly what you are looking for, don't be afraid to use it. If you learned somewhere that exception handling is not to be used for your own flow control, this does not apply to python. Liberal use of exception handling is considered pythonic, as in <a href="https://docs.python.org/2/glossary.html#term-eafp" rel="nofollow" title="EAFP">EAFP</a>.</p>

python short-circuiting