9.8. functools
— 高次関数と呼び出し可能オブジェクトの操作¶
バージョン 2.5 で追加.
ソースコード: Lib/functools.py
functools
モジュールは高次関数、つまり関数に影響を及ぼしたり他の関数を返したりする関数、のためのものです。一般に、どんな呼び出し可能オブジェクトでもこのモジュールの目的には関数として扱えます。
モジュール functools
は以下の関数を定義します:
-
functools.
cmp_to_key
(func)¶ 古いスタイルの比較関数を key function に変換します。 key 関数を受け取る関数 (
sorted()
,min()
,max()
,heapq.nlargest()
,heapq.nsmallest()
,itertools.groupby()
など) と共に使用します。この関数は、主に比較関数をサポートしていない Python 3 への移行のためのツールとして用意されています。比較関数は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])¶ これは
reduce()
関数と同じものです。このモジュールからも使えるようにしたのは 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])¶ wrapper 関数を wrapped 関数に見えるようにアップデートします。オプション引数はタプルで、元の関数のどの属性がラッパ関数の対応する属性に直接代入されるか、またラッパ関数のどの属性が元の関数の対応する属性でアップデートされる(updated)か、を指定します。これらの引数のデフォルト値はモジュールレベル定数 WRAPPER_ASSIGNMENTS (ラッパ関数の __name__ 、__module__ 、そしてドキュメンテーション文字列 __doc__ に代入します) と WRAPPER_UPDATES (ラッパ関数の __dict__ 、すなわちインスタンス辞書をアップデートします) です。
この関数は主に関数を包んでラッパを返すデコレータ (decorator) 関数の中で使われるよう意図されています。もしラッパ関数がアップデートされないとすると、返される関数のメタデータは元の関数の定義ではなくラッパ関数の定義を反映してしまい、これは通常あまり有益ではありません。
-
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()
のドキュメンテーション文字列は失われたところです。