Pythonic способ сделать это состоит в том, чтобы создать итератор, что-то вроде:
from datetime import datetime, timedelta
class dater(object):
def __init__(self, first, lastPlusOne, inclusiveEnd = False):
# Store important stuff, adjusting end if you want it inclusive.
self.__oneDay = timedelta(days = 1)
self.__curr = datetime.strptime(first, "%Y-%m-%d").date()
self.__term = datetime.strptime(lastPlusOne, "%Y-%m-%d").date()
if inclusiveEnd:
self.__term += self.__oneDay
def __iter__(self):
return self
def __next__(self):
return self.next()
def next(self):
# This is the meat. It checks to see if the generator is
# exhausted and raises the correct exception if so. If not,
# it saves the current, calculates the next, stores that
# for the next time, then returns the saved current.
if self.__curr >= self.__term:
raise StopIteration()
(cur, self.__curr) = (self.__curr, self.__curr + self.__oneDay)
return cur
Вы можете вызвать его как-то вроде (из вашего примера):
for date in dater("2019-09-21", "2019-10-09", inclusiveEnd=True):
print(date)
дляget:
2019-09-21
2019-09-22
2019-09-23
2019-09-24
2019-09-25
: no need to show it all, trust me :-)
2019-10-08
2019-10-09
Преимущество использования итератора состоит в том, что:
- код для его использования становится очень простым
for
циклом, похожим на многие другие методы Python;и - вы можете сделать конструктор
__init__
произвольно сложным (например, принимая переменные datetime
или date
, а также текущие строки).
Эта последняя точканесет некоторые дополнительные объяснения. В коде, который устанавливает self.__curr
(например), вы можете использовать что-то вроде этого:
if type(first) == type(date(2000, 1, 1)): # copy a date.
self.__curr = first
elif type(first) == type(datetime(2000, 1, 1)): # extract date from datetime.
self.__curr = first.date()
else: # convert string.
self.__curr = datetime.strptime(first, "%Y-%m-%d").date()
Это будет определять тип источника и корректировать поведение, так что вы получите date
независимо от этого. Если вы сделаете то же самое для окончательной даты, вы получите действительно адаптируемый итератор, который может даже начинаться и заканчиваться различными представлениями:
for mydate in dater("2000-01-01", datetime.now()):
process_every_date_from_start_of_2000_to_yesterday(mydate)