0

Can someone please explain to me how the below works:

class Memoize:
    def __init__(self, f):
        self.f = f
        self.memo = {}
    def __call__(self, *args):
        if not args in self.memo:
            self.memo[args] = self.f(*args)
        return self.memo[args]

Then:

def factorial(k):
    if k < 2: return 1
    return k * factorial(k - 1)

factorial = Memoize(factorial)

This is taken from this question. I would like to understand how does self.f(*args) work. args is a tuple of positional arguments. When I try to do:

*(1,2,3)

I get syntax error. I thought it's some kind on unpacking operator or something like that. Does asterisk with a tuple mean anything independently or does it exist only in the context of a function call? Thank you for any explanations.

Community
  • 1
  • 1
ducin
  • 25,621
  • 41
  • 157
  • 256

1 Answers1

1

It /is/ an unpacking operator. However, it doesn't always work that way when called directly in the interpreter. Check this out:

In [90]: def addThese(a,b,c):
   ....:     print 'a', a
   ....:     print 'b', b
   ....:     print 'c', c
   ....:     print 'a+b+c', a+b+c
   ....:     return a+b+c
   ....: 

In [91]: args = (1,3,5)

In [92]: addThese(1,3,5)
a 1
b 3
c 5
a+b+c 9
Out[92]: 9

In [93]: addThese(args)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-93-cc47562f352a> in <module>()
----> 1 addThese(args)

TypeError: addThese() takes exactly 3 arguments (1 given)

In [94]: addThese(*args)
a 1
b 3
c 5
a+b+c 9
Out[94]: 9
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241