How to chain Python function calls so the behaviour is as follows
This is my go at it:
def f(x=None, seq=''):
if x:
return 'f' + seq + x
else:
def g(y=None, p=seq + 'o'):
return f(y, p)
return g
Edit If you really need the function signature to be f(x=None)
, use this:
def f(x=None):
def f_(x=None, seq=''):
if x:
return 'f' + seq + x
else:
def g(y=None, p=seq + 'o'):
return f_(y, p)
return g
return f_(x)
:^)
An alternative to Nikola's answer is something like this:
def f(s=None):
if s: return f'f{s}'
def factory(prefix):
def inner(s=None):
return f'f{prefix}{s}' if s else factory(prefix + 'o')
return inner
return factory('o')
using a closure and no helper function.
You can try this:
def f(s=None):
string = "f"
def ret(p=None):
nonlocal string
string += "o"
return ret if not p else string + p
return ret if not s else string + s
Obviously, you need to store the number of 'o' somewhere in the memory (e.g. the code) of f
. To achieve this, you can benefit from these 2 features of Python:
- You can define functions inside other functions
- There's this thing called argument binding which allows you to tell Python to fix the some or all of the arguments of your function. This is done through
functools.partial
And here's the solution
from functools import partial
def f(s=None):
# Define a new function g which takes the current text and takes s
def g(current_text, s=None):
if s is not None:
return current_text + s
else:
# If called with an empty argument, just rebind current_text with an extra o
return partial(g, current_text + "o")
# Just call g with the initial conditions
return g("f", s)
print(f()()()()()("s")) # fooooos
print(f("s")) # fs