1

I have a function like this:

def test():
    x = "3" # In actual code, this is computed

    if x is None:
        return None

    y = "3"

    if y is None:
        return None

    z = "hello"

    if z is None:
        return None

Is there a way of making the if statement go away and abstract it with some function. I'm expecting something like this:

def test():
    x = "3"
    check_None(x)

    y = "3"
    check_None(y)

    z = "hello"
    check_None(z)

Ideally, check_None should alter the control flow if the parameter passed to it is None. Is this possible?

Note: Working on Python 2.7.

chepner
  • 497,756
  • 71
  • 530
  • 681
Sibi
  • 47,472
  • 16
  • 95
  • 163
  • 3
    Only if `check_None` raises an exception that `test` doesn't catch - it can't force `test` to `return None`. – jonrsharpe Jun 13 '15 at 12:33
  • @jonrsharpe Ok, I think I get the idea. Yes `test` doesn't catch it. – Sibi Jun 13 '15 at 12:36
  • Does `z` depend on `y`, and `y` depend on `x`? BTW, I know this is only semantics, but `if` is not a loop, and you can write on one line if that makes you happier. – cdarke Jun 13 '15 at 12:41
  • @cdarke Yes, they depend. On some cases, they don't. But I want to just avoid the if checks and abstract it over a function. – Sibi Jun 13 '15 at 12:45
  • OK, so how is `None` generated in the calculations? Is it returned by some other function in a module? – cdarke Jun 13 '15 at 12:48
  • @cdarke Yes, None is returned by some other function. – Sibi Jun 13 '15 at 12:51
  • Not counting side effects from calculating x, y and z - your function can be replaced by "def test(): pass". What do you want to return from your test function if all of them are not None? – folkol Jun 13 '15 at 13:45

2 Answers2

2

You can easily code it in some thing like this.

def test():
    #compute x, y, z
    if None in [x, y, z]:
       return None
    # proceed with rest of code

An even better way would be to use an generator to generate value x, y, z so that you only does computation for one value at a time.

def compute_values():
    yield compute_x()
    yield compute_y()
    yield compute_z()

def test():
    for value in compute_values():
        if value is None:
           return None
hspandher
  • 15,934
  • 2
  • 32
  • 45
0

I am not really sure if we should do it like this, but one of the hacks could be like this, Also create your own exception class and only catch that particular exception so that no other exceptions are accidentally caught by the except and return None.

class MyException(Exception):
    pass

def check_none(x):
    if x is None:
        raise MyException

def test():
    try:
        z=None
        check_none(z)
    except MyException, e:
        return None

return_value = test()
Namit Singal
  • 1,506
  • 12
  • 26
  • Don't use exceptions for flow control - http://stackoverflow.com/questions/3259660/example-of-using-exceptions-to-control-flow – julka Jun 13 '15 at 12:50
  • @julka I'm actually ok with exceptions to achieve what I want. But in this solution I want `check_none` to return None and don't want `try-except` blocks. – Sibi Jun 13 '15 at 12:53
  • @Sibi: this is really what exception handling is for. – cdarke Jun 13 '15 at 13:07
  • @Sibi You do not want try, except outside of the function, is that right? Inside the function would be ok? – Namit Singal Jun 13 '15 at 13:23