Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] - نسخه متنی

David Ascher, Alex Martelli, Anna Ravenscroft

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Recipe 16.5. Composing Functions


Credit: Scott David Daniels


Problem



You need to
construct a new function by composing existing functions (i.e., each
call of the new function must call one existing function on its
arguments, then another on the result of the first one).


Solution


Composition is a fundamental operation between functions and yields a
new function as a result. The new function must call one existing
function on its arguments, then another on the result of the first
one. For example, a function that, given a string, returns a copy
that is lowercase and does not have leading and trailing blanks, is
the composition of the existing string.lower and
string.strip functions. (In this case, it does not
matter in which order the two existing functions are applied, but
generally, it could be important.)

A closure (a nested function returned from
another function) is often the best Pythonic approach to constructing
new functions:

def compose(f, g, *args_for_f, **kwargs_for_f):
''' compose functions. compose(f, g, x)(y) = f(g(y), x)) '''
def fg(*args_for_g, **kwargs_for_g):
return f(g(*args_for_g, **kwargs_for_g), *args_for_f, **kwargs_for_f)
return fg
def mcompose(f, g, *args_for_f, **kwargs_for_f):
''' compose functions. mcompose(f, g, x)(y) = f(*g(y), x)) '''
def fg(*args_for_g, **kwargs_for_g):
mid = g(*args_for_g, **kwargs_for_g)
if not isinstance(mid, tuple):
mid = (mid,)
return f(*(mid+args_for_f), **kwargs_for_f)
return fg


Discussion


The closures in this recipe show two styles of function composition.
I separated mcompose and
compose because I think of the two possible forms
of function composition as being quite different, in mathematical
terms. In practical terms, the difference shows only when the second
function being composed, g, returns a tuple. The
closure returned by compose passes the result of
g as f's first
argument anyway, while the closure returned by
mcompose treats it as a tuple of arguments to pass
along. Any extra arguments provided to either
compose or mcompose are treated as
extra arguments for f (there is no standard
functional behavior to follow here):

compose(f, g, x)(y) = f(g(y), x)
mcompose(f, g, x)(y) = f(*g(y), x)

As in currying (see Recipe 16.4), this
recipe's functions are for constructing functions
from other functions. Your goal in so doing should be clarity, since
no efficiency is gained by using these functional forms.

Here's a quick example for interactive use:

parts = compose(' '.join, dir)

When called on a module object, the callable we just bound to name
parts gives you an easy-to-view string
that lists the module's contents.


See Also


Recipe 16.4 for an example
of "curry"ing (i.e., associating
parameters with partially evaluated functions).


/ 394