问题
I have two functions each calling the other on their final line as a means of passing control. Is there an elegant way to force one function to exit before the other gets executed, so that you don't stack your program up on corpses?
Example:
def f1(x):
print("f1",x)
f2(x+1)
def f2(x):
print("f2",x)
f1(x+1)
f1(0)
The way it is now, after ~1000 calls it runs into the recursion limit.
Of cause, a simple external control structure would get rid of the problem, but I'd rather have the control flow engraved in the functions.
Edit:
But isn't this rather hindering?
If Python strives to be a high-level language with a high level of abstraction, at some point of building modules upon modules, wouldn't Python collapse on its own behavior of not reducing its footprint?
回答1:
If you want one function to exit before the other is called, you will have to actually exit the function instead of having it call the other one:
def f1(x):
print('f1', x)
return f2, (x+1,)
def f2(x):
print('f2', x)
return f1, (x+1,)
f, args = f1, (0,)
while True:
f, args = f(*args)
This will require that external control structure you wanted to avoid.
As an aside, the way you're trying to make function calls work is a lot like GOTO, and can end up having the same effects on program complexity and maintainability.
回答2:
The easiest way would be to set a condition in your function in order to terminate/stop the recursion.
It could be something like this:
def f1(x):
if x == 30: #Set a limit in order to just print, without calling
print("f1", x)
else:
print("f1",x)
f2(x+1)
def f2(x):
print("f2",x)
f1(x+1)
f1(0)
回答3:
Simple solution
You could just add an if statement:
def f1(x):
print("f1", x)
if x <= 30:
f2(x+1)
def f2(x):
print("f2",x)
if x <= 30:
f1(x+1)
Long answer
The answer to if you can force the function to quit before calling the next function is no-ish. Specifically you are asking for a tail-recursion optimization which python does not optimize.
回答4:
As user2357112 has pointed out, I'm not sure why you would want to do this.
However, if you really have to do this then you can assign a boolean value to the function to indicate that it has been called already.
def f1(x):
print("f1",x)
f1.called = True
if not f2.called:
f2(x+1)
def f2(x):
print("f2",x)
f2.called = True
if not f1.called:
f1(x+1)
f1(0)
来源:https://stackoverflow.com/questions/45514448/how-to-force-a-function-to-exit-after-calling-another-function