| Conditions | 5 |
| Total Lines | 53 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
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:
If many parameters/temporary variables are present:
| 1 | # -*- coding: utf-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 |