Generator vs functools.partial?

J. Cliff Dyer jcd at sdf.lonestar.org
Thu Jun 21 12:15:08 EDT 2012


On Thu, 2012-06-21 at 21:25 +1000, John O'Hagan wrote:
> Sometimes a function gets called repeatedly with the same expensive argument:
> 
> def some_func(arg, i):
>     (do_something with arg and i)
> 
> same_old_arg = big_calculation()
> for i in lots_of_items:
>     some_func(same_old_arg, i)
> 

Another possibility is to refactor this into a callable class.

    class DoesSomethingWithExpensiveData(object):
        def __init__(self, arg):
            self.arg = arg

        def __call__(self, operand):
            return sum([self.arg, operand])

    func = DoesSomethingWithExpensiveData(big_calculation()):
    for thing in a_bunch_of_things:
        print func(thing)

Or you can write a function factory:

    def get_func(arg):
        def inner(operand):
            return sum([arg, operand])
        return inner

    func = get_func(big_calculation())
    for thing in a_bunch_of_things:
        print func(thing)


> A simple case like that looks OK, but it can get messy when groups of arguments
> are passed between functions, especially if the arguments are used by functions
> called within the functions they are passed to (by other functions!).
> 
> Maybe that's a code smell, but it can be cleaned up with:
> 
> import functools
> some_func = functools.partial(some_func, big_calculation())
> for i in lots_of_items:
>     some_func(i)
> 
> But what about a generator?
> 
> def some_func():
>     arg = big_calculation()
>     while 1:
>         i = yield
>         (do_something with arg and i)
> 
> some_gen = some_func()
> some_gen.send(None)
> for i in lots_of_items:
>     some_gen.send(i)
> 
> I like this because it encapsulates the calculation of the arguments
> inside the function that is using them without repeating it, and there are no
> restrictions on argument order like partial. But sending None is annoying. :)
> 
> Old news? Thoughts, criticisms, theories?
> 
> --
> 
> John	





More information about the Python-list mailing list