"functools" — 高階関数と呼び出し可能オブジェクトの操作
******************************************************

バージョン 2.5 で追加.

**ソースコード:** Lib/functools.py

======================================================================

"functools" モジュールは高階関数、つまり関数に影響を及ぼしたり他の関数
を返したりする関数のためのものです。一般に、どんな呼び出し可能オブジェ
クトでもこのモジュールの目的には関数として扱えます。

モジュール "functools" は以下の関数を定義します:

functools.cmp_to_key(func)

   Transform an old-style comparison function to a *key function*.
   Used with tools that accept key functions (such as "sorted()",
   "min()", "max()", "heapq.nlargest()", "heapq.nsmallest()",
   "itertools.groupby()").  This function is primarily used as a
   transition tool for programs being converted to Python 3 where
   comparison functions are no longer supported.

   比較関数は2つの引数を受け取り、それらを比較し、 「より小さい」 場合
   は負の数を、同値の場合には 0 を、 「より大きい」 場合には正の数を返
   す、あらゆる呼び出し可能オブジェクトです。key 関数は呼び出し可能オ
   ブジェクトで、1つの引数を受け取り、ソートキーとして使われる値を返し
   ます。

   以下はプログラム例です:

      sorted(iterable, key=cmp_to_key(locale.strcoll))  # locale-aware sort order

   ソートの例と簡単なチュートリアルは ソート HOW TO を参照して下さい。

   バージョン 2.7 で追加.

functools.total_ordering(cls)

   ひとつ以上の拡張順序比較メソッド (rich comparison ordering methods)
   を定義したクラスを受け取り、残りを実装するクラスデコレータです。こ
   のデコレータは全ての拡張順序比較演算をサポートするための労力を軽減
   します:

   引数のクラスは、 "__lt__()", "__le__()", "__gt__()", "__ge__()" の
   中からどれか1つと、 "__eq__()" メソッドを定義する必要があります。

   例えば:

      @total_ordering
      class Student:
          def __eq__(self, other):
              return ((self.lastname.lower(), self.firstname.lower()) ==
                      (other.lastname.lower(), other.firstname.lower()))
          def __lt__(self, other):
              return ((self.lastname.lower(), self.firstname.lower()) <
                      (other.lastname.lower(), other.firstname.lower()))

   バージョン 2.7 で追加.

functools.reduce(function, iterable[, initializer])

   This is the same function as "reduce()".  It is made available in
   this module to allow writing code more forward-compatible with
   Python 3.

   バージョン 2.6 で追加.

functools.partial(func[,*args][, **keywords])

   新しい "partial" オブジェクトを返します。このオブジェクトは呼び出さ
   れると位置引数 *args* とキーワード引数 *keywords* 付きで呼び出され
   た *func* のように振る舞います。呼び出しに際してさらなる引数が渡さ
   れた場合、それらは *args* に付け加えられます。追加のキーワード引数
   が渡された場合には、それらで *keywords* を拡張または上書きします。
   大雑把にいうと、次のコードと等価です:

      def partial(func, *args, **keywords):
          def newfunc(*fargs, **fkeywords):
              newkeywords = keywords.copy()
              newkeywords.update(fkeywords)
              return func(*(args + fargs), **newkeywords)
          newfunc.func = func
          newfunc.args = args
          newfunc.keywords = keywords
          return newfunc

   関数 "partial()" は、関数の位置引数・キーワード引数の一部を「凍結」
   した部分適用として使われ、簡素化された引数形式をもった新たなオブジ
   ェクトを作り出します。例えば、 "partial()" を使って *base* 引数のデ
   フォルトが 2 である "int()" 関数のように振る舞う呼び出し可能オブジ
   ェクトを作ることができます:

   >>> from functools import partial
   >>> basetwo = partial(int, base=2)
   >>> basetwo.__doc__ = 'Convert base 2 string to an int.'
   >>> basetwo('10010')
   18

functools.update_wrapper(wrapper, wrapped[, assigned][, updated])

   Update a *wrapper* function to look like the *wrapped* function.
   The optional arguments are tuples to specify which attributes of
   the original function are assigned directly to the matching
   attributes on the wrapper function and which attributes of the
   wrapper function are updated with the corresponding attributes from
   the original function. The default values for these arguments are
   the module level constants *WRAPPER_ASSIGNMENTS* (which assigns to
   the wrapper function’s *__name__*, *__module__* and *__doc__*, the
   documentation string) and *WRAPPER_UPDATES* (which updates the
   wrapper function’s *__dict__*, i.e. the instance dictionary).

   この関数は主に関数を包んでラッパーを返す *デコレータ* 関数の中で使
   われるよう意図されています。もしラッパー関数がアップデートされない
   とすると、返される関数のメタデータは元の関数の定義ではなくラッパー
   関数の定義を反映してしまい、これは通常あまり有益ではありません。

functools.wraps(wrapped[, assigned][, updated])

   これはラッパー関数を定義するときに "update_wrapper()" を関数デコレ
   ータとして呼び出す便宜関数です。これは "partial(update_wrapper,
   wrapped=wrapped, assigned=assigned, updated=updated)" と等価です。
   例えば:

      >>> from functools import wraps
      >>> def my_decorator(f):
      ...     @wraps(f)
      ...     def wrapper(*args, **kwds):
      ...         print 'Calling decorated function'
      ...         return f(*args, **kwds)
      ...     return wrapper
      ...
      >>> @my_decorator
      ... def example():
      ...     """Docstring"""
      ...     print 'Called example function'
      ...
      >>> example()
      Calling decorated function
      Called example function
      >>> example.__name__
      'example'
      >>> example.__doc__
      'Docstring'

   このデコレータ・ファクトリを使用しないと、上の例中の関数の名前は
   "'wrapper'" となり、元の "example()" のドキュメンテーション文字列は
   失われてしまいます。


"partial" オブジェクト
======================

"partial" オブジェクトは、 "partial()" 関数によって作られる呼び出し可
能オブジェクトです。オブジェクトには読み取り専用の属性が三つあります:

partial.func

   呼び出し可能オブジェクトまたは関数です。 "partial" オブジェクトの呼
   び出しは新しい引数とキーワードと共に "func" に転送されます。

partial.args

   最左の位置引数で、 "partial" オブジェクトの呼び出し時にその呼び出し
   の際の位置引数の前に追加されます。

partial.keywords

   "partial" オブジェクトの呼び出し時に渡されるキーワード引数です。

"partial" オブジェクトは "function" オブジェクトのように呼び出し可能で
、弱参照可能で、属性を持つことができます。重要な相違点もあります。例え
ば、 "__name__" と "__doc__" 両属性は自動では作られません。また、クラ
ス中で定義された "partial" オブジェクトはスタティックメソッドのように
振る舞い、インスタンスの属性問い合わせの中で束縛メソッドに変換されませ
ん。
