Sridhar Ratnakumar
Sridhar Ratnakumar

Reputation: 85462

Elegant way to abstract multiple function calls?

Example:

>>> def write_to_terminal(fmt, *args):
...     print fmt % args
>>> LOG = logging.getLogger(__name__)
>>> info = multicall(write_to_terminal, LOG.info)
>>> debug = multicall(write_debug_to_terminal, LOG.debug)
>>> ...
>>> info('Hello %s', 'guido') # display in terminal *and* log the message

Is there an elegant way to write multicall? Perhaps with the help of the standard library .. without reinventing the wheel?

Upvotes: 1

Views: 330

Answers (1)

Steef
Steef

Reputation: 34685

Something like this?

def multicall(*functions):
    def call_functions(*args, **kwds):
        for function in functions:
            function(*args, **kwds)
    return call_functions

And if you want to aggregate the results:

def multicall(*functions):
    def call_functions(*args, **kwds):
        return [function(*args, **kwds) for function in functions]
    return call_functions

EDIT

Decorators were suggested; in that case it would look like this:

def appendcalls(*functions):
    def decorator(decorated_function):
        all_functions = [decorated_function] + list(functions)
        def call_functions(*args, **kwds):
            for function in all_functions:
                function(*args, **kwds)
        return call_functions
    return decorator


LOG = logging.getLogger(__name__)

@appendcalls(LOG.info)
def info(fmt, *args):
    print fmt % args

info('Hello %s', 'guido')

appendcalls() takes any number of functions to be called after the decorated function. You may want to implement the decorator differently, depending on what return value you want -- the original from the decorated function, a list of all function results or nothing at all.

Upvotes: 5

Related Questions