I'm trying to write a decorator that 'refreshes' after being called, but where the refreshing only occurs once after the last function exits. Here is an example:
@auto_refresh
def a():
print "In a"
@auto_refresh
def b():
print "In b"
a()
If a()
is called, I want the refresh function to be run after exiting a()
. If b()
is called, I want the refresh function to be run after exiting b()
, but not after a()
when called by b()
. Here is an example of a class that does this:
class auto_refresh(object):
def __init__(self, f):
print "Initializing decorator"
self.f = f
def __call__(self, *args, **kwargs):
print "Before function"
if 'refresh' in kwargs:
refresh = kwargs.pop('refresh')
else:
refresh = False
self.f(*args, **kwargs)
print "After function"
if refresh:
print "Refreshing"
With this decorator, if I run
b()
print '---'
b(refresh=True)
print '---'
b(refresh=False)
I get the following output:
Initializing decorator
Initializing decorator
Before function
In b
Before function
In a
After function
After function
---
Before function
In b
Before function
In a
After function
After function
Refreshing
---
Before function
In b
Before function
In a
After function
After function
So when written this way, not specifying the refresh
argument means that refresh is defaulted to False
. Can anyone think of a way to change this so that refresh
is True
when not specified? Changing the
refresh = False
to
refresh = True
in the decorator does not work:
Initializing decorator
Initializing decorator
Before function
In b
Before function
In a
After function
Refreshing
After function
Refreshing
---
Before function
In b
Before function
In a
After function
Refreshing
After function
Refreshing
---
Before function
In b
Before function
In a
After function
Refreshing
After function
because refresh then gets called multiple times in the first and second case, and once in the last case (when it should be once in the first and second case, and not in the last case).