I've started a new project of mine, and I'd like to create a function, we'll call it foo
, which remembers the previous calls made to it.
So if for example the function should return the last parameter used we should have this:
print(foo(2), foo(7), foo('a'))
print out:
None 2 7
How can we create a decorator function, called bar
for example, which prints the given arguments unless the previous function call is the same as the previous one, in that case the function prints nothing and simply returns None.
So far I was able to create a skeleton of the function, looking like this:
@bar
def printer(*args):
print(*args)
and in the bar function I should check the previous call somehow, but I don't know how! I don't want to use global variables or something but only use the function. I assume I need to use closures for the bar
and foo
funcs. Could you me how to implement them?
NOTE this is what should happen for these calls:
printer("a") # prints a
printer("a") # only returns None
printer("a") # only returns None
printer("b") # prints b
printer("a") # prints a
First write a version of foo
that you want your decorator to produce, for example
def foo(arg, prev=[]):
if arg in prev[-1:]:
return None
else:
prev.append(arg)
return arg
>>> print(foo(1), foo(2), foo(2), foo(3))
1 2 None 3
Now you know what you want the decorator to do.
def bar(f):
def bar(arg, prev=[]):
if arg in prev[-1:]:
return None
else:
prev.append(arg)
return(f(arg))
return bar
Now redefine foo
without the memory, but wrapped in the decorator:
@bar
def foo(arg):
return arg
>>> print(foo(1), foo(2), foo(2), foo(3))
1 2 None 3