很奇怪的腐败行为

2024-09-22 14:36:13 发布

您现在位置:Python中文网/ 问答频道 /正文

使用pip上最新的dateutil,当使用一个循环的DAILYrrule调用count方法时,我得到了奇怪的时间和顺序依赖行为。在

>>> 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

Tags: pip方法importdatetimecount时间rulesdaily
1条回答
网友
1楼 · 发布于 2024-09-22 14:36:13

答案很简单,这是因为在创建规则集时没有包含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

你可以从当前时间开始获取条目,最高可达微秒。在

过了一段时间,当你再次尝试-

^{pr2}$

您再次创建了一个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(),它仍然会返回相同的计数。在

我不能百分之百地确定它是一个bug还是它打算这样做,很可能是一个bug。在

我已经为此打开了issue。在

相关问题 更多 >