functools —呼び出し可能なオブジェクトの高階関数と操作—Pythonドキュメント
functools —呼び出し可能なオブジェクトに対する高階関数と操作
ソースコード: :source: `Lib / functools.py`
functools モジュールは、高階関数、つまり他の関数に作用するか、他の関数を返す関数用です。 一般に、このモジュールでは、呼び出し可能なオブジェクトを関数として扱うことができます。
functools モジュールは、次の関数を定義します。
- @functools.cached_property(func)
クラスのメソッドをプロパティに変換します。このプロパティの値は一度計算されてから、インスタンスの存続期間中、通常の属性としてキャッシュされます。 property()に似ていますが、キャッシュが追加されています。 それ以外の場合は事実上不変であるインスタンスの高価な計算プロパティに役立ちます。
例:
バージョン3.8の新機能。
ノート
このデコレータでは、各インスタンスの
__dict__
属性が可変マッピングである必要があります。 これは、メタクラス(タイプインスタンスの__dict__
属性はクラス名前空間の読み取り専用プロキシであるため)や、__slots__
を指定するタイプなどの一部のタイプでは機能しないことを意味します。定義されたスロットの1つとしてのX214X] (このようなクラスは、__dict__
属性をまったく提供しません)。
- functools.cmp_to_key(func)
古いスタイルの比較関数をキー関数に変換します。 キー関数を受け入れるツール( sorted()、 min()、 max()、 heapq.nlargest()[X122Xなど)で使用されます]、 heapq.nsmallest()、 itertools.groupby())。 この関数は主に、比較関数の使用をサポートするPython2から変換されるプログラムの移行ツールとして使用されます。
比較関数は、2つの引数を受け入れ、それらを比較し、より小さい場合は負の数、等しい場合はゼロ、より大きい場合は正の数を返す呼び出し可能関数です。 キー関数は、1つの引数を受け入れ、ソートキーとして使用される別の値を返す呼び出し可能関数です。
例:
並べ替えの例と簡単な並べ替えチュートリアルについては、並べ替え方法を参照してください。
バージョン3.2の新機能。
- @functools.lru_cache(user_function)
@functools.lru_cache(maxsize=128, typed=False) maxsize 最新の呼び出しまで保存するメモ化呼び出し可能オブジェクトで関数をラップするデコレータ。 高価な関数またはI / Oバウンド関数が同じ引数で定期的に呼び出されると、時間を節約できます。
ディクショナリは結果をキャッシュするために使用されるため、関数の定位置引数とキーワード引数はハッシュ可能である必要があります。
個別の引数パターンは、個別のキャッシュエントリを持つ個別の呼び出しと見なすことができます。 たとえば、 f(a = 1、b = 2)と f(b = 2、a = 1)はキーワード引数の順序が異なり、2つの別々のキャッシュエントリを持つ場合があります。
user_function が指定されている場合は、呼び出し可能である必要があります。 これにより、 lru_cache デコレータをユーザー関数に直接適用し、 maxsize をデフォルト値の128のままにすることができます。
maxsize が
None
に設定されている場合、LRU機能は無効になり、キャッシュは無制限に増大する可能性があります。typed がtrueに設定されている場合、異なるタイプの関数引数は個別にキャッシュされます。 たとえば、
f(3)
とf(3.0)
は別個の呼び出しとして扱われ、別個の結果が得られます。キャッシュの有効性を測定し、 maxsize パラメーターを調整するために、ラップされた関数には、ヒットを示す名前付きタプルを返す
cache_info()
関数が組み込まれています。 、ミス、最大サイズおよびカーソルサイズ。 マルチスレッド環境では、ヒットとミスは概算です。デコレータは、キャッシュをクリアまたは無効にするための
cache_clear()
関数も提供します。元の基礎となる関数には、
__wrapped__
属性を介してアクセスできます。 これは、イントロスペクション、キャッシュのバイパス、または関数を別のキャッシュで再ラップする場合に役立ちます。LRU(最近使用されていない)キャッシュは、最新の通話が今後の通話の最良の予測因子である場合に最適に機能します(たとえば、ニュースサーバーで最も人気のある記事は毎日変更される傾向があります)。 キャッシュのサイズ制限により、Webサーバーなどの長時間実行されるプロセスに制限されることなくキャッシュが増大することはありません。
一般に、LRUキャッシュは、以前に計算された値を再利用する場合にのみ使用する必要があります。 したがって、副作用のある関数、呼び出しごとに個別の可変オブジェクトを作成する必要のある関数、またはtime()やrandom()などの不純な関数をキャッシュすることは意味がありません。
静的WebコンテンツのLRUキャッシュの例:
キャッシュを使用してフィボナッチ数を効率的に計算し、動的計画法手法を実装する例:
バージョン3.2の新機能。
バージョン3.3で変更: typed オプションが追加されました。
バージョン3.8で変更: user_function オプションが追加されました。
- @functools.total_ordering
1つ以上の豊富な比較順序付けメソッドを定義するクラスが与えられると、このクラスデコレータが残りを提供します。 これにより、可能なすべての豊富な比較操作を指定する作業が簡素化されます。
クラスは、
__lt__()
、__le__()
、__gt__()
、または__ge__()
のいずれかを定義する必要があります。 さらに、クラスは__eq__()
メソッドを提供する必要があります。例えば:
ノート
このデコレータを使用すると、正常に動作する完全に順序付けられた型を簡単に作成できますが、実行が遅くなり、派生した比較メソッドのスタックトレースが複雑になるという犠牲が伴います。 パフォーマンスベンチマークがこれが特定のアプリケーションのボトルネックであることを示している場合、代わりに6つの豊富な比較方法すべてを実装すると、簡単に速度を上げることができます。
バージョン3.2の新機能。
バージョン3.4で変更:認識されない型の基になる比較関数からNotImplementedを返すことがサポートされるようになりました。
- functools.partial(func, /, *args, **keywords)
新しい部分オブジェクトを返します。これは、呼び出されると、位置引数 args およびキーワード引数キーワードで呼び出された func のように動作します。 呼び出しにさらに引数が指定されると、それらは args に追加されます。 追加のキーワード引数が指定されている場合、それらはキーワードを拡張およびオーバーライドします。 ほぼ同等:
partial()は、関数の引数やキーワードの一部を「フリーズ」して、署名が簡略化された新しいオブジェクトを生成する部分関数アプリケーションに使用されます。 たとえば、 partial()を使用して、 int()関数のように動作する呼び出し可能オブジェクトを作成できます。 base 引数のデフォルトは次の2つです。
- class functools.partialmethod(func, /, *args, **keywords)
partial のように動作する、新しい partialmethod 記述子を返します。ただし、直接呼び出すことはできず、メソッド定義として使用するように設計されています。
func は、記述子または呼び出し可能である必要があります(通常の関数と同様に、両方のオブジェクトは記述子として処理されます)。
func が記述子(通常のPython関数、 classmethod()、 staticmethod()、
abstractmethod()
の別のインスタンスなど)の場合X152X] partialmethod )、__get__
の呼び出しは基になる記述子に委任され、適切な partial object が結果として返されます。func が記述子以外の呼び出し可能である場合、適切なバインドされたメソッドが動的に作成されます。 これは、メソッドとして使用すると通常のPython関数のように動作します。引数およびキーワードが指定される前であっても、 self 引数が最初の位置引数として挿入されます。 partialmethod コンストラクターに。
例:
バージョン3.4の新機能。
- functools.reduce(function, iterable[, initializer])
iterable の項目に、2つの引数の function を左から右に累積的に適用して、iterableを1つの値に減らします。 たとえば、
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
は((((1+2)+3)+4)+5)
を計算します。 左の引数 x は累積値であり、右の引数 y は iterable からの更新値です。 オプションの initializer が存在する場合、計算ではiterableの項目の前に配置され、iterableが空の場合のデフォルトとして機能します。 initializer が指定されておらず、 iterable にアイテムが1つしかない場合、最初のアイテムが返されます。ほぼ同等:
すべての中間値を生成するイテレータについては、 itertools.accumulate()を参照してください。
- @functools.singledispatch
関数をシングルディスパッチ ジェネリック関数に変換します。
ジェネリック関数を定義するには、
@singledispatch
デコレータでデコレートします。 ディスパッチは最初の引数の型で発生することに注意してください。それに応じて関数を作成してください。オーバーロードされた実装を関数に追加するには、ジェネリック関数の
register()
属性を使用します。 デコレータです。 タイプで注釈が付けられた関数の場合、デコレータは最初の引数のタイプを自動的に推測します。型注釈を使用しないコードの場合、適切な型引数をデコレータ自体に明示的に渡すことができます。
ラムダと既存の関数の登録を有効にするために、
register()
属性を関数形式で使用できます。register()
属性は、デコレータのスタッキング、ピクルス化、および各バリアントの単体テストの作成を個別に可能にする、装飾されていない関数を返します。呼び出されると、ジェネリック関数は最初の引数の型でディスパッチします。
特定のタイプの実装が登録されていない場合は、そのメソッド解決順序を使用して、より一般的な実装を見つけます。
@singledispatch
で装飾された元の関数は、ベースのobject
タイプに登録されています。つまり、より適切な実装が見つからない場合に使用されます。ジェネリック関数が特定のタイプに対してどの実装を選択するかを確認するには、
dispatch()
属性を使用します。登録されているすべての実装にアクセスするには、読み取り専用の
registry
属性を使用します。バージョン3.4の新機能。
バージョン3.7で変更:
register()
属性は、型注釈の使用をサポートします。
- class functools.singledispatchmethod(func)
メソッドをシングルディスパッチ ジェネリック関数に変換します。
一般的なメソッドを定義するには、
@singledispatchmethod
デコレータでデコレートします。 ディスパッチは最初のnon-selfまたはnon-cls引数の型で発生することに注意してください。それに応じて、関数を作成してください。@singledispatchmethod
は、@classmethod
などの他のデコレータとのネストをサポートします。dispatcher.register
を許可するには、singledispatchmethod
が最も外側のデコレータである必要があることに注意してください。 これがNegator
クラスで、neg
メソッドがクラスにバインドされています。同じパターンを他の同様のデコレータにも使用できます:
staticmethod
、abstractmethod
など。バージョン3.8の新機能。
- functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
wrapper 関数を wrapped 関数のように更新します。 オプションの引数は、元の関数のどの属性がラッパー関数の一致する属性に直接割り当てられ、ラッパー関数のどの属性が元の関数の対応する属性で更新されるかを指定するタプルです。 これらの引数のデフォルト値は、モジュールレベルの定数
WRAPPER_ASSIGNMENTS
(ラッパー関数の__module__
、__name__
、__qualname__
、__annotations__
に割り当てられます)です。 ]および__doc__
、ドキュメント文字列)およびWRAPPER_UPDATES
(ラッパー関数の__dict__
を更新します。 インスタンス辞書)。イントロスペクションやその他の目的で元の機能にアクセスできるようにするため(例: lru_cache())などのキャッシングデコレータをバイパスすると、この関数は、ラップされている関数を参照するラッパーに
__wrapped__
属性を自動的に追加します。この関数の主な使用目的は、装飾された関数をラップしてラッパーを返すデコレータ関数です。 ラッパー関数が更新されていない場合、返される関数のメタデータは、元の関数定義ではなくラッパー定義を反映します。これは通常、役に立たないものです。
update_wrapper()は、関数以外の呼び出し可能オブジェクトで使用できます。 ラップされているオブジェクトから欠落している assigned または updated で指定された属性はすべて無視されます(つまり、 この関数は、ラッパー関数にそれらを設定しようとはしません)。 ラッパー関数自体に updated で指定された属性がない場合、 AttributeError は引き続き発生します。
バージョン3.2の新機能:
__wrapped__
属性の自動追加。バージョン3.2の新機能:デフォルトで
__annotations__
属性のコピー。バージョン3.2で変更:属性がない場合、 AttributeError がトリガーされなくなりました。
バージョン3.4で変更:
__wrapped__
属性は、その関数が__wrapped__
属性を定義している場合でも、常にラップされた関数を参照するようになりました。 (:issue: `17482` を参照)
- @functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
これは、ラッパー関数を定義するときに関数デコレータとして update_wrapper()を呼び出すための便利な関数です。
partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)
と同等です。 例えば:このデコレータファクトリを使用しないと、サンプル関数の名前は
'wrapper'
になり、元のexample()
のdocstringは失われます。
部分的オブジェクト
partial オブジェクトは、 partial()によって作成された呼び出し可能なオブジェクトです。 これらには、3つの読み取り専用属性があります。
- partial.args
- partial オブジェクト呼び出しに提供される位置引数の前に付加される左端の位置引数。
- partial.keywords
- partial オブジェクトが呼び出されたときに提供されるキーワード引数。
partial オブジェクトは、呼び出し可能、弱い参照可能、および属性を持つことができるという点でfunction
オブジェクトに似ています。 いくつかの重要な違いがあります。 たとえば、 __ name __ および__doc__
属性は自動的に作成されません。 また、クラスで定義された partial オブジェクトは静的メソッドのように動作し、インスタンス属性のルックアップ中にバインドされたメソッドに変換されません。