使用pip上提供的最新dateutil,使用循环count
规则调用DAILY
方法时,我得到了奇怪的时间和与排序有关的行为。
>>> import dateutil
>>> dateutil.__version__
'2.4.2'
>>> from dateutil import rrule
>>> import datetime
>>> rules = rrule.rruleset()
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179 # ??? Expected 0
>>> rules = rrule.rruleset()
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179 # ??? Expected 0
>>> rules = rrule.rruleset()
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
0
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
0 # Now its working???
>>> rules = rrule.rruleset()
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179 # ??? Expected 0
>>> rules = rrule.rruleset()
>>> rules.count()
0
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
0 # WHAT???
>>> rules.count()
0
>>> rules = rrule.rruleset()
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179 # IM DONE... WTF
最佳答案
答案很简单,因为创建规则集时未包含dtstart
参数,当不包含该参数时,默认值为当前时间datetime.datetime.now()
,并且包含直到当前微秒的分量。
因此,当您首次使用-创建规则集时
>>> rules = rrule.rruleset()
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
>>> rules.count()
8179
您可以从当前时间开始(不超过微秒)开始输入。
一段时间后,当您再次尝试-
rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0)))
您将从当前时间开始再次创建
rrule.rrule
对象,因此它与您在rules
中创建的上一个对象不同。要解决此问题,您可以指定
dtstart
属性以确保它同时启动。范例-
>>> rules = rrule.rruleset()
>>> rules.rrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0), dtstart=datetime.datetime(now.year,now.month,now.day,0,0,0)))
>>> rules.count()
8179
>>> rules.exrule(rrule.rrule(rrule.DAILY, until=datetime.datetime(2038,1,1,0,0,0), dtstart=datetime.datetime(now.year,now.month,now.day,0,0,0)))
>>> l3 = list(rules)
>>> len(l3)
0
>>> rules.count()
0
在其他示例中,也会发生类似的问题。
鉴于上述情况,我认为dateutil代码中存在一个问题,即当您第一次调用
count()
时,它们实际上是在缓存规则集的计数(长度),然后仅在对其进行迭代时才重新计算其正确长度,等等该问题出现在
rrulebase
类中,该类是ruleset
的基类。来自的代码是(source-https://github.com/dateutil/dateutil/blob/master/dateutil/rrule.py)-def count(self):
""" Returns the number of recurrences in this set. It will have go
trough the whole recurrence, if this hasn't been done before. """
if self._len is None:
for x in self:
pass
return self._len
因此,即使在应用
exrule()
之后,如果您以前曾调用过.count()
,它也将继续返回相同的计数。我不是100%知道它是否有错误,或是否打算这样做,很可能是错误。
我已经为此打开issue。
关于python - 非常奇怪的行为集行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31957080/