Python with语句调用pd.read_excel报AttributeError:__enter__错误
Python入职日期校验脚本报错排查
问题背景
编写入职日期校验Python脚本,预期实现逻辑:
- 读取
Upcoming Hires.xlsx文件内New Hires工作表的Start Date字段 - 优先校验下周一是否存在入职记录
- 若下周一无入职记录,顺延校验下周二的入职记录
- 若两个日期均无匹配记录,输出「无下周入职人员」提示
脚本运行时在with pd.read_excel代码行触发AttributeError: __enter__错误,无法定位问题原因。
原始问题代码
import os import pandas as pd import datetime as DT from dateutil.relativedelta import relativedelta, MO, TU hr_file = "Upcoming Hires.xlsx" with pd.read_excel(hr_file, sheet_name="New Hires",parse_dates=["Start Date"]) as reader: now = now = DT.datetime.now() nm = now - relativedelta(weekday=MO(+1)) next_monday = now - relativedelta(weekday=MO(+1)) if next_monday in reader: print("true") if not next_monday in reader: nm = now - relativedelta(weekday=TU(+2)) next_monday = nm.strftime("%#m/%#d/%#y") if next_monday in reader: print("had to move the date for the start date to tuesday but it True") if not next_monday in reader: print("error: there is no starter next week...")
报错栈信息
AttributeError Traceback (most recent call last) c:\masterscript\test.py in <cell line: 1>() ----> 7 with pd.read_excel(hr_file, sheet_name="New Hires",parse_dates=["Start Date"]) as reader: 8 now = now = DT.datetime.now() 9 nm = now - relativedelta(weekday=MO(+1)) AttributeError: __enter__
报错根因
pandas.read_excel()方法的返回值是DataFrame对象,该对象没有实现上下文管理器协议(不存在__enter__内置方法),无法和with语句搭配使用,这是触发本次报错的直接原因。
除此之外原代码还存在3个逻辑问题,会导致即使修复语法错误也无法得到预期结果:
- 日期计算逻辑错误:原代码用减法计算下周一/周二的逻辑完全错误,且
relativedelta的周偏移参数写法有误,无法正确取到下周的周一、周二日期 - 存在判断逻辑错误:直接用
日期 in DataFrame的写法,只会判断该值是否存在于DataFrame的列名中,不会遍历Start Date列的数值做匹配 - 日期类型不统一:计算得到的下周一为datetime类型,下周二被手动转成了字符串格式,和
parse_dates解析得到的datetime类型日期无法匹配
修正后可运行代码
import pandas as pd import datetime as DT from dateutil.relativedelta import relativedelta, MO, TU hr_file = "Upcoming Hires.xlsx" # 移除错误的with语句,直接赋值获取DataFrame对象 df = pd.read_excel(hr_file, sheet_name="New Hires", parse_dates=["Start Date"]) # 统一提取日期部分做比较,忽略时分秒精度影响 df["Start Date"] = df["Start Date"].dt.date now = DT.datetime.now().date() # 正确计算下周一:当前日期之后的第一个周一 next_monday = now + relativedelta(weekday=MO(1)) # 正确计算下周二 next_tuesday = now + relativedelta(weekday=TU(1)) if next_monday in df["Start Date"].values: print(f"下周一({next_monday})存在入职记录") elif next_tuesday in df["Start Date"].values: print(f"下周一无入职记录,下周二({next_tuesday})存在入职记录") else: print("提示:下周一周二均无入职人员")
内容的提问来源于stack exchange,提问作者charles rushin
相关产品推荐
相关产品推荐

