make a parent function return – super return?

Question:

there is a check I need to perform after each subsequent step in a function, so I wanted to define that step as a function within a function.

>>> def gs(a,b):
...   def ry():
...     if a==b:
...       return a
...
...   ry()
...
...   a += 1
...   ry()
...
...   b*=2
...   ry()
... 
>>> gs(1,2) # should return 2
>>> gs(1,1) # should return 1
>>> gs(5,3) # should return 6
>>> gs(2,3) # should return 3

so how do I get gs to return ‘a’ from within ry? I thought of using super but think that’s only for classes.

Thanks

There’s been a little confusion… I only want to return a if a==b. if a!=b, then I don’t want gs to return anything yet.

edit: I now think decorators might be the best solution.

Asked By: Jiaaro

||

Answers:

Do you mean?

def gs(a,b):
    def ry():
        if a==b:
            return a
    return ry()
Answered By: S.Lott

you return ry() explicitly instead of just calling it.

Answered By: user54650

There’s been a little confusion… I
only want to return a if a==b. if
a!=b, then I don’t want gs to return
anything yet.

Check for that then:

def gs(a,b):
    def ry():
        if a==b:
            return a
    ret = ry()
    if ret: return ret
    # do other stuff
Answered By: lawrence

As you mention “steps” in a function, it almost seems like you want a generator:

def gs(a,b):
  def ry():
    if a==b:
      yield a
  # If a != b, ry does not "generate" any output
  for i in ry():
    yield i
  # Continue doing stuff...
  yield 'some other value'
  # Do more stuff.
  yield 'yet another value'

(Generators can now also act as coroutines, since Python 2.5, using the new yield syntax.)

Answered By: Alec Thomas

This should allow you to keep checking the state and return from the outer function if a and b ever end up the same:

def gs(a,b):
    class SameEvent(Exception):
        pass
    def ry():
        if a==b:
            raise SameEvent(a)
    try:
        # Do stuff here, and call ry whenever you want to return if they are the same.
        ry()

        # It will now return 3.
        a = b = 3
        ry()

    except SameEvent as e:
        return e.args[0]
Answered By: Mike Boers

I had a similar problem, but solved it by simply changing the order of the call.

def ry ()
    if a==b 
        gs()

in some languages like javascript you can even pass a function as a variable in a function:

function gs(a, b, callback) {
   if (a==b) callback();
}

gs(a, b, ry);

I came here looking for an answer to the same type of problem. Instead I worked out a solution that (at least for me) makes the intent a bit more clear: define your steps as lambdas or defs, and place them in an array. Then you can simply loop and handle them as needed.

I adapted my solution to the OP’s question below:

def gs(a,b):
   def step1():
      nonlocal a
      a += 1

   def step2():
      nonlocal b
      b *= 2

   if a == b:
      return a

   steps = [step1, step2]
   for step in steps:
      step()
      if a == b:
         return a
      # anything you else you want to do
Answered By: jobu1342