Reputation: 6820
I have encountered a very weird situation in Python.
I have a while True:
loop in a script that constantly grabs real-time data. The data is only meant to be grabbed during business hours, therefore I have a helper function in a module called lib/date.py
.
This is the function:
def isTime(utc_now=datetime.datetime.utcnow()):
'''
9:00 AM UTC - 5:00 PM UTC Mon - Fri.
The parameter utc_now can be used to specify a specific
datetime to be checked instead of the utcnow().
'''
week_day = utc_now.weekday()
# no good on Saturdays and Sundays
if 5 == week_day or 6 == week_day:
return False
now_int = (utc_now.hour * 60) + utc_now.minute
if (17 * 60) >= now_int >= (9 * 60):
return True
return False
I realize that the way times are checked is an overkill, but this is a simplified version of my function. My real function also includes a bunch of time zone conversions which make the above necessary.
This is my main script (simplified):
def main():
while True:
do_ten_seconds()
def do_ten_seconds():
log.info("alive")
for i in xrange(10):
if isTime():
log.info("its time")
# do data grabbing
sleep(1)
This works perfectly during the week, stopping every week night and continuing the next morning. However, on the weekend, it does not "recover" from the long break. In other words, isTime
never returns True
Monday morning.
I checked the log, and the script just prints "alive" every 10 seconds, but the data grabbing part never happens (and "its time" is never printed). Hence, I am assuming this means isTime
is returning False
.
Could it be that because the function is called so frequently over the weekend, and because it returns False
so many times in a row, Python caches the results and never recovers from it?
When I spawn the same instance of code while the main script is still running in the faulty mode where isTime
is returning False
, the new instance gets True
from isTime
and begins to work perfectly.
What is going on?
Upvotes: 2
Views: 303
Reputation: 799240
Default arguments are calculated at compile time. Make the default value None
, and check for that using is None
.
Upvotes: 2
Reputation: 90017
The first time you import date.py, the following line is run once:
def isTime(utc_now=datetime.datetime.utcnow()):
When it's run, the default value for utc_now
is set to the time at that instant, and is never recomputed.
Upvotes: 5