バージョン 2.5 で追加.
モジュール functools は高階関数、つまり関数に対する関数、あるいは他の関数を返す関数、のためのものです。一般に、どんな呼び出し可能オブジェクトでもこのモジュールの目的には関数として扱えます。
モジュール functools では以下の関数を定義します。
これは 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() のドキュメンテーション文字列は失われたところです。