You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用holidays库生成2005年节假日列表时函数崩溃原因

问题排查与修复方案

报错根本原因

holidays库提供的UnitedStates节假日实例并非静态字典,内部实现了惰性加载逻辑:部分节假日不会在类初始化阶段完成计算写入,而是在用户首次通过[date]语法访问对应日期的节日名称时,才会动态计算该节日并写入实例的字典结构中。

你在列表推导式中同时执行遍历实例和访问实例key取节日名两个操作,遍历过程中访问key触发了新条目写入,导致字典大小在迭代时发生变化,抛出对应运行时错误。2005年无特殊属性,仅刚好触发了该版本holidays库美国节假日的惰性加载逻辑,其余年份的节假日在初始化阶段已全部加载完成,访问key不会修改字典结构,因此无报错。

隐藏隐患

你代码中列表推导式的临时变量名与函数入参date重名,会在推导式作用域内覆盖入参值,属于潜在逻辑错误,需要修正。

修复代码

遍历前先将节假日实例的所有键值对转为静态列表,完全加载所有节假日后再遍历,即可避免惰性加载带来的字典修改问题,优化后的代码如下:

import datetime, holidays
import dateutil.easter as easter

def to_date(date_string):
    return datetime.datetime.strptime(date_string,'%Y-%m-%d').date()

def is_trading_holiday(date):
    us_holidays = holidays.UnitedStates(years=date.year)
    # 剔除哥伦布日和退伍军人节,美股上述节日正常交易
    exclude_holidays = {"Columbus Day", "Columbus Day (Observed)", "Veterans Day", "Veterans Day (Observed)"}
    # 先转成静态items列表,触发全量加载后再遍历,避免迭代时修改原字典
    custom_holidays = [
        holiday_date
        for holiday_date, holiday_name in list(us_holidays.items())
        if holiday_name not in exclude_holidays
    ]
    # 追加耶稣受难日,美股当日休市
    custom_holidays.append(easter.easter(year=date.year) - datetime.timedelta(days=2))
    return date in custom_holidays

if __name__=="__main__":
    first_date = to_date('2020-01-03')
    second_date = to_date('2015-11-26') # 感恩节
    third_date = to_date('2005-01-01') # 新年
    fourth_date = to_date('2005-01-07')

    print(is_trading_holiday(first_date))
    print(is_trading_holiday(second_date))
    print(is_trading_holiday(third_date))
    print(is_trading_holiday(fourth_date))

优化说明:将需要排除的节日存储结构从列表改为集合,in判断的时间复杂度从O(n)降至O(1),可提升大量日期校验时的性能。

内容的提问来源于stack exchange,提问作者Grant Moore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:48:05