Reputation: 396
This is a program to compute factorial number with cache.
def run_closure():
f = cache(factorial)
print("5! = %d" % f(5))
print("5! = %d" % f(5))
print("4! = %d" % f(4))
pass
def run_decorator():
print("5! = %d" % factorial(5))
print("5! = %d" % factorial(5))
print("4! = %d" % factorial(4))
pass
def cache(func):
table = {}
def wrapper(n):
if n in table:
print("%d is in memo." % n)
return table[n]
else:
print("f(%d) is called." % n)
table[n] = func(n)
return table[n]
return wrapper
# @cache # comment for "run_closure()"; uncomment for "run_decorator"
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
def main():
run_closure()
# run_decorator()
pass
if __name__ == "__main__":
main()
pass
I implement this by means of closure and decorator. The former output:
f(5) is called.
5! = 120
5 is in memo.
5! = 120
f(4) is called.
4! = 24
The latter output:
f(5) is called.
f(4) is called.
f(3) is called.
f(2) is called.
f(1) is called.
f(0) is called.
5! = 120
5 is in memo.
5! = 120
4 is in memo.
4! = 24
In the former case, when 5!
is computed, the previous n!(n<5)
should have been computed and saved into table
but it didn't. The latter case is what I want. So what's the difference between closure and decorator? Any help is appreciated.
Upvotes: 1
Views: 1720
Reputation: 85
Decorators, in the general sense, are functions or classes that wrap around another object, that extend or decorate the object. The decorator supports the same interface as the wrapped function or object, so the receiver doesn't even know the object has been decorated.
A closure is an anonymous function that refers to its parameters or other variables outside its scope.
So basically, decorators use closures, and not replace them.
Upvotes: 1
Reputation: 7877
Using decorator, you change the function itself, and its new version is called recursively. When using closure on the way you do it behaves different: you create function f, which internally keeps calling factorial
. If you set factorial=cache(factorial)
, it will behave exactly the same as decorated does.
Upvotes: 2