JachymDvorak
JachymDvorak

Reputation: 149

Iterate over list of objects, which can be tuples or objects

I have a list of functions that all take a number, do something to it and then return transformed number, some of them accept extra arguments, some not.

def foo(num):
    return num + 5

def bar(num, arg1: int):
    return num + 5 + arg1

class ApplyFuncs:
    
    def apply_funcs(self, num, funcs):
        
        for func in funcs:
            num = func(num)
        
        return num 

I need to make an object of these functions and their arguments and apply them all to my number in a different class, sort of like a pipeline.

I can either use functools.partial like so:

from functools import partial
ApplyFuncs().apply_funcs(num=5,
                         funcs=[
                             foo,
                             partial(bar, arg1=5)
                         ])

but that requires for potential user to know to use partial.

I was thinking of submitting a tuple (func, dict of args) like so:

ApplyFuncs().apply_funcs(num=5,
                         funcs=[
                             foo,
                             (bar, args=dict(arg1=5))
                         ])

but then what do I submit when the func requires no extra args? If I don't, I'm unable to iterate over the list as some objects have 2 elements (tuples) and some 1 (single object).

I would be able to write a more complex logic that unwraps the objects, categorizes them into either tuples or single objects, and then applies based on that, but that seems to be overkill.

Do you know if there's an easier, more pythonic way?

Upvotes: 0

Views: 37

Answers (1)

JachymDvorak
JachymDvorak

Reputation: 149

Well, I solved it quite elegantly (imo). I will probably use this.

def apply_funcs(num)
        for obj in self.function_list:
            if callable(obj):
                num = obj(num)
            else:
                num = obj[0](num, **obj[1])
        return num

Upvotes: 1

Related Questions