1

I have a common pattern that goes like

def f(x):
  if x.type == 'Failure':
     # return `x` immediately without doing work
     return x
  else:
  # do stuff with x...
  return x

I would like to abstract the if/else pattern into a stand alone function. However I want that function, when called from inside f, to return from f immediately. Else it should just return x to a value inside f for further processing. Something like

def g(x):
  if x.type == 'Failure':
    global return x
  else:
    return x.value

def f(x):
  x_prime = g(x) # will return from f
                 # if x.type == 'Failure'
  # do some processing...
  return x_prime

Is this possible in Python?

8
  • Are you asking if it's possible at all, or if there's a quick shortcut for doing it in Python? It's certainly quite possible and relatively easy to put in the logic yourself, such as by returning a tuple from g instead of a single value, and using one of the values in the tuple to tell f to return immediately or not. That's just one example of how you could do it, but it's not necessarily something built-in in Python. Commented Nov 8, 2018 at 0:45
  • @RandomDavis I want to abstract that, so I can use g everywhere without changing code that only handles x.value. I'm thinking a decorator function could be a neat solution, but I welcome other alternatives. Yes, an actual solution would be better than a plain yes or no! Commented Nov 8, 2018 at 0:48
  • I doubt you can do this, and it seems like a bad idea in the first place. A function should not make assumptions about how the caller will use its result. Commented Nov 8, 2018 at 1:10
  • 1
    The only language I can think of where this could be done is Common Lisp, using a macro that expands into a RETURN expression. And even then, its behavior would depend on where it's used, because RETURN will exit the closest enclosing loop or function. Commented Nov 8, 2018 at 1:15
  • 2
    In Scheme you could do it with a function that takes a second argument, a continuation to call in the case where you want to do the global return. Commented Nov 8, 2018 at 1:16

1 Answer 1

2

I'm using Validation from my branch of pycategories:

def fromSuccess(fn):
    """
    Decorator function. If the decorated function
    receives Success as input, it uses its value.
    However if it receives Failure, it returns
    the Failure without any processing.
    Arguments:
        fn :: Function
    Returns:
        Function
    """
    def wrapped(*args, **kwargs):
        d = kwargs.pop('d')
        if d.type == 'Failure':
            return d
        else:
            kwargs['d'] = d.value
        return fn(*args, **kwargs)
    return wrapped

@fromSuccess
def return_if_failure(d):
    return d * 10

return_if_failure(d = Failure(2)), return_if_failure(d = Success(2))

>>> (Failure(2), 20)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.