LoginSignup
4
4

More than 5 years have passed since last update.

Pythonのキーワード引数も含めてmemoizeしたい

Last updated at Posted at 2012-11-15

Pythonwikiには次のようなmemoizeデコレータが紹介されています。

# note that this decorator ignores **kwargs
def memoize(obj):
    cache = obj.cache = {}

    @functools.wraps(obj)
    def memoizer(*args, **kwargs):
        if args not in cache:
            cache[args] = obj(*args, **kwargs)
        return cache[args]
    return memoizer

ただ、コメントに書いてあるとおり、kwargsには対応していない様子。では対応しましょう。

# do not use "self" for a name of argument.
import inspect
def memoize(obj):
    cache = obj.cache = {}

    @functools.wraps(obj)
    def memoizer(*args, **kwargs):
        argdict = inspect.getcallargs(obj, *args, **kwargs)
        argdict.pop('self', None) # if obj is a bound method, arguments includes "self"
        argset = frozenset(argdict.iteritems()) # for Python3, use dict.items() instead
        if argset not in cache:
            cache[argset] = obj(*args, **kwargs)
        return cache[argset]
    return memoizer

肝は、標準ライブラリのinspectを使うこと。
inspect.getcallargs()は

>>> def f(a, b, c=10):
...     pass
... 
>>> inspect.getcallargs(f, 1, 2) 
{'a': 1, 'c': 10, 'b': 2}

みたいに、引数の名前と引数を辞書にしてくれます。
inspectは色々便利です。

4
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4