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

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

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

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

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

@functools.cache(user_function)

   簡単で軽量な無制限の関数キャッシュです。 "メモ化 (memoize)" とも呼
   ばれることがあります。

   "lru_cache(maxsize=None)" と同じ関数を返し、関数の引数に対するルッ
   クアップ辞書を含む薄いラッパーを生成します。キャッシュ上の古い値を
   追い出す必要がないため、キャッシュサイズに制限のある "lru_cache()"
   よりも軽量で高速です。

   例えば:

      @cache
      def factorial(n):
          return n * factorial(n-1) if n else 1

      >>> factorial(10)      # no previously cached result, makes 11 recursive calls
      3628800
      >>> factorial(5)       # just looks up cached value result
      120
      >>> factorial(12)      # makes two new recursive calls, the other 10 are cached
      479001600

   バージョン 3.9 で追加.

@functools.cached_property(func)

   クラスのメソッドを、値を一度だけ計算して通常の属性としてキャッシュ
   するプロパティに変換します。キャッシュはインスタンスの生存期間にわ
   たって有効です。計算コストが高く、一度計算すればその後は不変である
   ようなインスタンスのプロパティに対して有用です。

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

      class DataSet:

          def __init__(self, sequence_of_numbers):
              self._data = tuple(sequence_of_numbers)

          @cached_property
          def stdev(self):
              return statistics.stdev(self._data)

   "cached_property()" のしくみは "property()" とやや異なります。通常
   のプロパティは、セッター (setter) が定義されない限り書き込みを禁止
   します。対照的に、 *cached_property* は書き込みを許します。

   *cached_property* デコレータはルックアップテーブルで、同名の属性が
   存在しない場合のみ動作します。動作した場合、 *cached_property* は同
   名の属性に書き込みを行います。その後の属性の読み込みと書き込みは
   *cached_property* メソッドより優先され、通常の属性のように働きます
   。

   キャッシュされた値は属性を削除することで取り除くことができます。こ
   れにより *cached_property* メソッドを再度実行することが可能になりま
   す。

   このデコレータは **PEP 412** のキー共有辞書のインターフェースを持ち
   ます。これは、インスタンス辞書がより多くのスペースを使う可能性があ
   ることを意味します。

   また、このデコレータは各インスタンスの "__dict__" 属性が可変のマッ
   ピングであることを要求します。すなわち、このデコレータはいくつかの
   型、たとえばメタクラス (型インスタンスの "__dict__" 属性はクラスの
   名前空間に対する読み込み専用のプロキシであるため) や、 "__slots__"
   を指定していてその中に "__dict__" を含まない型 (それ自体が
   "__dict__" 属性を提供しないため) に対しては動作しないことを意味しま
   す。

   可変なマッピングを持たないか、またはスペース効率の良いキー共有が必
   要な場合は、 "cached_property()" と似たような効果を "cache()" の上
   に "property()" を重ねることで実現できます:

      class DataSet:
          def __init__(self, sequence_of_numbers):
              self._data = sequence_of_numbers

          @property
          @cache
          def stdev(self):
              return statistics.stdev(self._data)

   バージョン 3.8 で追加.

functools.cmp_to_key(func)

   古いスタイルの比較関数を *key function* に変換します。key 関数を受
   け取るツール ("sorted()", "min()", "max()", "heapq.nlargest()",
   "heapq.nsmallest()", "itertools.groupby()" など) と共に使用します。
   この関数は、主に比較関数を使っていた Python 2 からプログラムの移行
   のための変換ツールとして使われます。

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

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

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

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

   バージョン 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 とな
   ります:

      @lru_cache
      def count_vowels(sentence):
          sentence = sentence.casefold()
          return sum(sentence.count(vowel) for vowel in 'aeiou')

   *maxsize* が "None" に設定された場合は、LRU 機能は無効化され、キャ
   ッシュは際限無く大きくなります。

   *typed* が真に設定された場合は、関数の異なる型の引数が別々にキャッ
   シュされます。例えば、"f(3)" と "f(3.0)" は別の結果をもたらす別の呼
   び出しとして扱われます。

   ラップされた関数には "cache_parameters()" 関数が定義されます。この
   関数は *maxsize* と *typed* の値を含む "dict" を新規に生成して 返し
   ます。これは通知目的のみであり、戻り値の変更は何の効果もありません
   。

   キャッシュ効率の測定や *maxsize* パラメータの調整をしやすくするため
   、ラップされた関数には "cache_info()" 関数が追加されます。この関数
   は *hits*, *misses*, *maxsize*, *currsize* を示す *named tuple* を
   返します。マルチスレッド環境では、hits と misses は概算です。

   このデコレータは、キャッシュの削除と無効化のための "cache_clear()"
   関数も提供します。

   元々の基底の関数には、 "__wrapped__" 属性を通してアクセスできます。
   これはキャッシュを回避して、または関数を別のキャッシュでラップして
   、内観するのに便利です。

   >>`LRU (least recently used) キャッシュ`_<< は、最も新しい呼び出し
   が次の呼び出しで最も現れやすいとき (例えば、最もニュースサーバの人
   気の記事が日ごとに変わる傾向にある場合) に最も最も効率よくはたらき
   ます。キャッシュのサイズ制限は、キャッシュがウェブサーバの長期間に
   渡るプロセスにおける限界を超えては大きくならないことを保証します。

   一般的には、 LRU キャッシュは前回計算した値を再利用したいときにのみ
   使うべきです。 そのため、副作用のある関数、呼び出すごとに個別の可変
   なオブジェクトを作成する必要がある関数、 time() や random() のよう
   な純粋でない関数をキャッシュする意味はありません。

   静的 web コンテンツ の LRU キャッシュの例:

      @lru_cache(maxsize=32)
      def get_pep(num):
          'Retrieve text of a Python Enhancement Proposal'
          resource = 'https://www.python.org/dev/peps/pep-%04d/' % num
          try:
              with urllib.request.urlopen(resource) as s:
                  return s.read()
          except urllib.error.HTTPError:
              return 'Not Found'

      >>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
      ...     pep = get_pep(n)
      ...     print(n, len(pep))

      >>> get_pep.cache_info()
      CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)

   キャッシュを使って 動的計画法 の技法を実装し、フィボナッチ数 を効率
   よく計算する例:

      @lru_cache(maxsize=None)
      def fib(n):
          if n < 2:
              return n
          return fib(n-1) + fib(n-2)

      >>> [fib(n) for n in range(16)]
      [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

      >>> fib.cache_info()
      CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

   バージョン 3.2 で追加.

   バージョン 3.3 で変更: *typed* オプションが追加されました。

   バージョン 3.8 で変更: *user_function* オプションが追加されました。

   バージョン 3.9 で追加: "cache_parameters()" 関数が追加されました。

@functools.total_ordering

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

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

   例えば:

      @total_ordering
      class Student:
          def _is_valid_operand(self, other):
              return (hasattr(other, "lastname") and
                      hasattr(other, "firstname"))
          def __eq__(self, other):
              if not self._is_valid_operand(other):
                  return NotImplemented
              return ((self.lastname.lower(), self.firstname.lower()) ==
                      (other.lastname.lower(), other.firstname.lower()))
          def __lt__(self, other):
              if not self._is_valid_operand(other):
                  return NotImplemented
              return ((self.lastname.lower(), self.firstname.lower()) <
                      (other.lastname.lower(), other.firstname.lower()))

   注釈:

     このデコレータにより、完全に順序の付いた振る舞いの良い型を簡単に
     作ることができますが、実行速度は遅くなり、派生した比較メソッドの
     スタックトレースは複雑になります。性能ベンチマークにより、これが
     アプリケーションのボトルネックになっていることがわかった場合は、
     代わりに 6 つの拡張比較メソッドをすべて実装すれば、簡単にスピード
     アップを図れるでしょう。

   バージョン 3.2 で追加.

   バージョン 3.4 で変更: 認識できない型に対して下層の比較関数から
   NotImplemented を返すことがサポートされるようになりました。

functools.partial(func, /, *args, **keywords)

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

      def partial(func, /, *args, **keywords):
          def newfunc(*fargs, **fkeywords):
              newkeywords = {**keywords, **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

class functools.partialmethod(func, /, *args, **keywords)

   "partial" と似た動作をする新しい "partialmethod" 記述子 (デスクリプ
   タ) を返します。直接呼び出しではなく、メソッド定義としての使用が目
   的であることのみが、partial とは異なります。

   *func* は、*descriptor* または呼び出し可能オブジェクトである必要が
   あります (通常の関数など、両方の性質を持つオブジェクトは記述子とし
   て扱われます。)

   *func* が記述子 (Python の通常の関数、 "classmethod()"、
   "staticmethod()"、"abstractmethod()" または別の "partialmethod" の
   インスタンスなど) の場合、 "__get__" への呼び出しは下層の記述子に委
   譲され、返り値として適切な partial オブジェクト が返されます。

   *func* が記述子以外の呼び出し可能オブジェクトである場合、適切な束縛
   メソッドが動的に作成されます。この func は、メソッドとして使用され
   た場合、Python の通常の関数と同様に動作します。 "partialmethod" コ
   ンストラクタに *args* と *keywords* が渡されるよりも前に、 *self*
   引数が最初の位置引数として挿入されます。

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

      >>> class Cell:
      ...     def __init__(self):
      ...         self._alive = False
      ...     @property
      ...     def alive(self):
      ...         return self._alive
      ...     def set_state(self, state):
      ...         self._alive = bool(state)
      ...     set_alive = partialmethod(set_state, True)
      ...     set_dead = partialmethod(set_state, False)
      ...
      >>> c = Cell()
      >>> c.alive
      False
      >>> c.set_alive()
      >>> c.alive
      True

   バージョン 3.4 で追加.

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

   *iterable* の要素に対して、iterable を単一の値に短縮するような形で
   2 つの引数をもつ *function* を左から右に累積的に適用します。例えば
   、 "reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])" は
   "((((1+2)+3)+4)+5)" を計算します。左引数 *x* は累計の値になり、右引
   数 *y* は "iterable" から取り出した更新値になります。オプションの
   *initializer* が存在する場合、計算の際に iterable の先頭に置かれま
   す。また、 iterable が空の場合には標準の値になります。
   *initializer* が与えられておらず、 *iterable* が単一の要素しか持っ
   ていない場合、最初の要素が返されます。

   およそ次と等価です:

      def reduce(function, iterable, initializer=None):
          it = iter(iterable)
          if initializer is None:
              value = next(it)
          else:
              value = initializer
          for element in it:
              value = function(value, element)
          return value

   全ての中間値を返すイテレータについては "itertools.accumulate()" を
   参照してください。

@functools.singledispatch

   関数を *シングルディスパッチ* *ジェネリック関数* に変換します。

   To define a generic function, decorate it with the
   "@singledispatch" decorator. When defining a function using
   "@singledispatch", note that the dispatch happens on the type of
   the first argument:

      >>> from functools import singledispatch
      >>> @singledispatch
      ... def fun(arg, verbose=False):
      ...     if verbose:
      ...         print("Let me just say,", end=" ")
      ...     print(arg)

   To add overloaded implementations to the function, use the
   "register()" attribute of the generic function, which can be used
   as a decorator.  For functions annotated with types, the decorator
   will infer the type of the first argument automatically:

      >>> @fun.register
      ... def _(arg: int, verbose=False):
      ...     if verbose:
      ...         print("Strength in numbers, eh?", end=" ")
      ...     print(arg)
      ...
      >>> @fun.register
      ... def _(arg: list, verbose=False):
      ...     if verbose:
      ...         print("Enumerate this:")
      ...     for i, elem in enumerate(arg):
      ...         print(i, elem)

   型アノテーションを使っていないコードについては、デコレータに適切な
   型引数を明示的に渡せます:

      >>> @fun.register(complex)
      ... def _(arg, verbose=False):
      ...     if verbose:
      ...         print("Better than complicated.", end=" ")
      ...     print(arg.real, arg.imag)
      ...

   To enable registering *lambdas* and pre-existing functions, the
   "register()" attribute can also be used in a functional form:

      >>> def nothing(arg, verbose=False):
      ...     print("Nothing.")
      ...
      >>> fun.register(type(None), nothing)

   The "register()" attribute returns the undecorated function. This
   enables decorator stacking, "pickling", and the creation of unit
   tests for each variant independently:

      >>> @fun.register(float)
      ... @fun.register(Decimal)
      ... def fun_num(arg, verbose=False):
      ...     if verbose:
      ...         print("Half of your number:", end=" ")
      ...     print(arg / 2)
      ...
      >>> fun_num is fun
      False

   汎用関数は、呼び出されると 1 つ目の引数の型でディスパッチします:

      >>> fun("Hello, world.")
      Hello, world.
      >>> fun("test.", verbose=True)
      Let me just say, test.
      >>> fun(42, verbose=True)
      Strength in numbers, eh? 42
      >>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True)
      Enumerate this:
      0 spam
      1 spam
      2 eggs
      3 spam
      >>> fun(None)
      Nothing.
      >>> fun(1.23)
      0.615

   Where there is no registered implementation for a specific type,
   its method resolution order is used to find a more generic
   implementation. The original function decorated with
   "@singledispatch" is registered for the base "object" type, which
   means it is used if no better implementation is found.

   If an implementation is registered to an *abstract base class*,
   virtual subclasses of the base class will be dispatched to that
   implementation:

      >>> from collections.abc import Mapping
      >>> @fun.register
      ... def _(arg: Mapping, verbose=False):
      ...     if verbose:
      ...         print("Keys & Values")
      ...     for key, value in arg.items():
      ...         print(key, "=>", value)
      ...
      >>> fun({"a": "b"})
      a => b

   To check which implementation the generic function will choose for
   a given type, use the "dispatch()" attribute:

      >>> fun.dispatch(float)
      <function fun_num at 0x1035a2840>
      >>> fun.dispatch(dict)    # note: default implementation
      <function fun at 0x103fe0000>

   登録されたすべての実装にアクセスするには、読み出し専用の "registry"
   属性を使用します:

      >>> fun.registry.keys()
      dict_keys([<class 'NoneType'>, <class 'int'>, <class 'object'>,
                <class 'decimal.Decimal'>, <class 'list'>,
                <class 'float'>])
      >>> fun.registry[float]
      <function fun_num at 0x1035a2840>
      >>> fun.registry[object]
      <function fun at 0x103fe0000>

   バージョン 3.4 で追加.

   バージョン 3.7 で変更: The "register()" attribute now supports
   using type annotations.

class functools.singledispatchmethod(func)

   メソッドを *シングルディスパッチ* *ジェネリック関数* に変換します。

   To define a generic method, decorate it with the
   "@singledispatchmethod" decorator. When defining a function using
   "@singledispatchmethod", note that the dispatch happens on the type
   of the first non-*self* or non-*cls* argument:

      class Negator:
          @singledispatchmethod
          def neg(self, arg):
              raise NotImplementedError("Cannot negate a")

          @neg.register
          def _(self, arg: int):
              return -arg

          @neg.register
          def _(self, arg: bool):
              return not arg

   "@singledispatchmethod" supports nesting with other decorators such
   as "@classmethod". Note that to allow for "dispatcher.register",
   "singledispatchmethod" must be the *outer most* decorator. Here is
   the "Negator" class with the "neg" methods bound to the class,
   rather than an instance of the class:

      class Negator:
          @singledispatchmethod
          @classmethod
          def neg(cls, arg):
              raise NotImplementedError("Cannot negate a")

          @neg.register
          @classmethod
          def _(cls, arg: int):
              return -arg

          @neg.register
          @classmethod
          def _(cls, arg: bool):
              return not arg

   The same pattern can be used for other similar decorators:
   "@staticmethod", "@abstractmethod", and others.

   バージョン 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__" が常にラップされた関数を参照するよう
   になりました。(bpo-17482 を参照)

@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

   これはラッパー関数を定義するときに "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" オブジェクトはスタティックメソッドのように
振る舞い、インスタンスの属性問い合わせの中で束縛メソッドに変換されませ
ん。
