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.
Answers:
Do you mean?
def gs(a,b):
def ry():
if a==b:
return a
return ry()
you return ry() explicitly instead of just calling it.
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
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.)
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]
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
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.
Do you mean?
def gs(a,b):
def ry():
if a==b:
return a
return ry()
you return ry() explicitly instead of just calling it.
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
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.)
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]
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