バージョン 2.5 で追加.
functools モジュールは高階関数、つまり関数に対する関数、あるいは他の関数を返す関数、のためのものです。一般に、どんな呼び出し可能オブジェクトでもこのモジュールの目的には関数として扱えます。
参考
最新バージョンの functools の Python ソースコード
モジュール functools では以下の関数を定義します。
古いスタイルの比較関数を key 関数に変換します。 key 関数を受け取る関数 (sorted(), min(), max(), heapq.nlargest(), heapq.nsmallest(), itertools.groupby() など) と共に使用します。この関数は、主に比較関数をサポートしていない Python 3.x への移行のためのツールとして用意されています。
比較関数は2つの引数を受け取り、それらを比較し、”より小さい” (less-than)の場合は負の値を、同値の場合には 0 を、 “より大きい” (greater-than) 場合には正の値を返します。 key 関数は1つの引数を受け取り、ある順序で並べた時の位置に相当する値を返します。
例:
sorted(iterable, key=cmp_to_key(locale.strcoll)) # ロケールに準拠したソート順
バージョン 2.7 で追加.
1つ以上のリッチ順序比較メソッドを定義したクラスを受け取り、残りを実装するクラスデコレータ。このデコレータは全てのリッチ順序比較演算をサポートするための労力を軽減します。
引数のクラスは、 __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 で追加.
これは reduce() 関数と同じものです。このモジュールからも使えるようにしたのは Python 3 と前方互換なコードを書けるようにするためです。
バージョン 2.6 で追加.
新しい 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
wrapper 関数を wrapped 関数に見えるようにアップデートします。オプション引数はタプルで、元の関数のどの属性が wrapper 関数の一致する属性に直接書き込まれる(assigned)か、また wrapper 関数のどの属性が元の関数の対応する属性でアップデートされる(updated)か、を指定します。これらの引数のデフォルト値はモジュール定数 WRAPPER_ASSIGNMENTS (wrapper 関数に __name__ 、 __module__ そしてドキュメンテーション文字列 __doc__ を書き込みます) と WRAPPER_UPDATES (wrapper 関数のインスタンス辞書をアップデートします) です。
この関数は主に関数を包んで wrapper を返すデコレータ関数(decorator) の中で使われるよう意図されています。もし wrapper 関数がアップデートされないとすると、返される関数のメタデータは元の関数の定義ではなく 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() のドキュメンテーション文字列は失われたところです。