[Python-Dev] functools.compose to chain functions together

Jason R. Coombs jaraco at jaraco.com
Fri Aug 14 20:39:03 CEST 2009


I'd like to express additional interest in python patch 1660179, discussed
here:

 

http://mail.python.org/pipermail/patches/2007-February/021687.html

 

On several occasions, I've had the desire for something like this.  I've
made due with lambda functions, but as was mentioned, the lambda is clumsy
and harder to read than functools.compose would be.

 

A potentially common use-case is when a library has a multi-decorator use
case in which they want to compose a meta decorator out of one or more
individual decorators.

 

Consider the hypothetical library.

 

# we have three decorators we use commonly

def dec_register_function_for_x(func):

                # do something with func

                return func

 

def dec_alter_docstring(func):

                # do something to func.__doc__

                return func

 

def inject_some_data(data):

                def dec_inject_data(func):

                                func.data = data # this may not be legal,
but assume it does something useful

                                return func

                return dec_inject_data

 

# we could use these decorators explicitly throughout our project

@dec_register_function_for_x

@dec_alter_docstring

@dec_inject_some_data('foo data 1')

def our_func_1(params):

                pass

 

@dec_register_function_for_x

@dec_alter_docstring

@dec_inject_some_data('foo data 2')

def our_func_2(params):

                pass

 

For two functions, that's not too onerous, but if it's used throughout the
application, it would be nice to abstract the collection of decorators.  One
could do this with lambdas.

 

def meta_decorator(data):

                return lambda func:
dec_register_function_for_x(dec_alter_docstring(dec_inject_some_data(data)(f
unc)))

 

But to me, a compose function is much easier to read and much more
consistent with the decorator usage syntax itself.

 

def meta_decorator(data):

return compose(dec_register_function_for_x, dec_alter_docstring,
dec_inject_some_data(data))

 

The latter implementation seems much more readable and elegant.  One doesn't
even need to know the decorator signature to effectively compose
meta_decorators.

 

I've heard it said that Python is not a functional language, but if that
were really the case, then functools would not exist. In addition to the
example described above, I've had multiple occasions where having a general
purpose function composition function would have simplified the
implementation by providing a basic functional construct. While Python isn't
primarily a functional language, it does have some functional constructs,
and this is one of the features that makes Python so versatile; one can
program functionally, procedurally, or in an object-oriented way, all within
the same language.

 

I admit, I may be a bit biased; my first formal programming course was
taught in Scheme.

 

Nevertheless, I believe functools is the ideal location for a very basic and
general capability such as composition.

 

I realize this patch was rejected, but I'd like to propose reviving the
patch and incorporating it into functools.

 

Regards,

Jason

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20090814/9344c932/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 6998 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-dev/attachments/20090814/9344c932/attachment-0001.bin>


More information about the Python-Dev mailing list