views:

527

answers:

6

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.

+10  A: 

Do you mean?

def gs(a,b):
    def ry():
        if a==b:
            return a
    return ry()
S.Lott
+1  A: 

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

+3  A: 

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
lawrence
+4  A: 

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.)

Alec Thomas
this isn't really the answer to my question, BUT it does solve the problem I was trying to achieve :)
Jiaaro
@All: You could use the yield only in the inner function if you want the outer function to remain a normal function, and not have to iterate over the result.
Mike Boers
+2  A: 

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]
Mike Boers
it's a little hackish, but I like it! very clever :)
Jiaaro
+1  A: 

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);