0
import collections
import functools

class memoized(object):
   '''Decorator. Caches a function's return value each time it is called.
   If called later with the same arguments, the cached value is returned
   (not reevaluated).
   '''
   def __init__(self, func):
      self.func = func
      self.cache = {}

   def __call__(self, *args):
      if not isinstance(args, collections.Hashable):
         # uncacheable. a list, for instance.
         # better to not cache than blow up.
         return self.func(*args)
      if args in self.cache:
         return self.cache[args]
      else:
         value = self.func(*args)
         self.cache[args] = value
         return value

   def __repr__(self):
      '''Return the function's docstring.'''
      return self.func.__doc__

   def __get__(self, obj, objtype):
      '''Support instance methods.'''
      return functools.partial(self.__call__, obj)

# simple class just to test
class Fib(object):

   @memoized
   def fibonacci(self, n):
      '''Return the nth fibonacci number.'''
      if n in (0, 1):
         return n
      return self.fibonacci(n-1) + self.fibonacci(n-2)

im having trouble understanding how the get descriptor works here i know its there to provide support for instance methods because memoized doesnt know what self refers to here, but i dont know how it fixes the problem under the hood ? how does get even get called here ?

Micheal
  • 23
  • 5
  • Have you read the [Python descriptor HOWTO](https://docs.python.org/3/howto/descriptor.html)? What wasn't clear from that? – Martijn Pieters Jan 25 '17 at 15:11
  • And unrelated: the `isinstance(args, collections.Hashable)` test will never fail, because `args` is always a tuple. However, hashing *can* still fail, if any of the arguments themselves are not hashable. `isinstance(([],), collections.Hashable)` is true, but `hash([])` throws an exception. – Martijn Pieters Jan 25 '17 at 15:14
  • @Martijn i know how get works and why we're using it here but i dont know how its solving the problem we have – Micheal Jan 25 '17 at 15:19
  • Have you tried *removing* the `__get__` method to see what happens? – Martijn Pieters Jan 25 '17 at 15:19
  • @MartijnPieters yes i have it fails because of 'self' and it makes sense my question is when and how get is called here – Micheal Jan 25 '17 at 15:21
  • That's why I linked to the descriptor howto. Read it. – Martijn Pieters Jan 25 '17 at 15:23
  • @MartijnPieters thanks that link really helped im gonna start reading the docs instead of other sources now :) – Micheal Jan 25 '17 at 15:31

0 Answers0