Completed
Pull Request — develop (#448)
by
unknown
37s
created

memoize()   B

Complexity

Conditions 5

Size

Total Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
c 1
b 0
f 0
dl 0
loc 53
rs 8.384

1 Method

Rating   Name   Duplication   Size   Complexity  
A _memoized_func() 0 11 4

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
# -*- coding: utf-8 -*-
2
from __future__ import absolute_import, division, print_function
3
from collections import Hashable
4
from types import GeneratorType
5
6
from six import wraps
7
8
9
def memoize(func):
10
    """
11
    Decorator to cause a function to cache it's results for each combination of
12
    inputs and return the cached result on subsequent calls.  Does not support
13
    named arguments or arg values that are not hashable.
14
15
    >>> @memoize
16
    ... def foo(x):
17
    ...     print('running function with', x)
18
    ...     return x+3
19
    ...
20
    >>> foo(10)
21
    running function with 10
22
    13
23
    >>> foo(10)
24
    13
25
    >>> foo(11)
26
    running function with 11
27
    14
28
    >>> @memoize
29
    ... def range_tuple(limit):
30
    ...     print('running function')
31
    ...     return tuple(i for i in range(limit))
32
    ...
33
    >>> range_tuple(3)
34
    running function
35
    (0, 1, 2)
36
    >>> range_tuple(3)
37
    (0, 1, 2)
38
    >>> @memoize
39
    ... def range_iter(limit):
40
    ...     print('running function')
41
    ...     return (i for i in range(limit))
42
    ...
43
    >>> range_iter(3)
44
    Traceback (most recent call last):
45
    TypeError: Can't memoize a generator or non-hashable object!
46
    """
47
    func._result_cache = {}  # pylint: disable-msg=W0212
48
49
    @wraps(func)
50
    def _memoized_func(*args, **kwargs):
51
        key = (args, tuple(sorted(kwargs.items())))
52
        if key in func._result_cache:  # pylint: disable-msg=W0212
53
            return func._result_cache[key]  # pylint: disable-msg=W0212
54
        else:
55
            result = func(*args, **kwargs)
56
            if isinstance(result, GeneratorType) or not isinstance(result, Hashable):
57
                raise TypeError("Can't memoize a generator or non-hashable object!")
58
            func._result_cache[key] = result  # pylint: disable-msg=W0212
59
            return result
60
61
    return _memoized_func
62