how to run nested partials

Question:

I have a set of nested partials that I’m trying to call:

print(my_partial)

functools.partial(<function g at 0x000001A047370598>,
    functools.partial(<function f at 0x000001A047370620>, 
        functools.partial(<function c at 0x000001A047370400>, 5)))

so when I try to run my partial I get the inner partial back:

print(my_partial)

functools.partial(<function f at 0x000001A047370620>, 
    functools.partial(<function c at 0x000001A047370400>, 5))

(Or sometihng like that). Anyway, so to run this to get the final transformation on 5 (the input data), I have to do this:

print(my_partial()()()())

25

Is there a functools function that I can pass this nested partials to so that it’ll just run it all for me? Something like this:

print(functools.run_partials(my_partial))

25

Does something like this exist? I hope so, the soltion I’m working on is buggy:

def run_nested(x):
    print(str(type(x())))
    if 'functools.partial' in str(type(x())):
        run_nested(x())
    print('DONE!', x())
    return x()
Asked By: MetaStack

||

Answers:

I don’t think there’s anything in functools to help. You could always keep calling it until it’s not callable anymore with a single while. Something like:

from functools import  partial

def f(fn):
    return fn

def g(fn):
    return fn

def c(n):
    return n*n

my_f = partial(g, partial(f, partial(c, 5) ))

print(my_f())
# functools.partial(<function f at 0x10eb7cd08>, functools.partial(<function c at 0x10eb7c598>, 5))

res = my_f
while(callable(res)):
    res = res()
print(res) # '25'
Answered By: Mark
def run_nested_partial(f):                                                  
    if isinstance(f, partial):                                              
        return f.func(                                                      
            *map(run_nested_partial, f.args),                               
            **{k: run_nested_partial(v) for k, v in f.keywords.items()}     
        )                                                                   
    return f   

                                                         
                                           
run_nested_partial(int.__add__, partial(int.__sub__, 2, 1), 3) # (2-1) + 3 = 4    
Answered By: Karolius
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.