Python Schedule模块报错TypeError:首个参数必须可调用
解决Python Schedule定时执行Excel刷新任务的报错问题
错误原因
你调用schedule.every(30).minutes.do(excel_update(directory_2))时,直接执行了excel_update(directory_2),把函数的返回值(None)传给了do方法,但do要求第一个参数必须是可调用的函数对象,而非函数执行结果,因此触发TypeError。
解决方案
1. 修正Schedule任务注册方式
将函数调用改为传递函数本身,并把参数作为do方法的后续参数传入:
schedule.every(30).minutes.do(excel_update, directory_2)
2. 优化Excel操作避免资源泄漏
原代码中每个Excel文件都创建一次Excel实例,效率低且易导致进程残留。建议将Excel实例的创建和销毁放在文件循环外:
def excel_update(directory): # 仅创建一次Excel实例 xlapp = win32.DispatchEx('Excel.Application') xlapp.DisplayAlerts = False xlapp.Visible = True try: for filename in os.listdir(directory): if filename.endswith(('.xlsx', '.xlsm')): file_path = os.path.join(directory, filename) print(f"正在处理:{file_path}") xlbook = xlapp.Workbooks.Open(file_path) xlbook.RefreshAll() # 等待异步刷新完成(可根据数据量调整等待逻辑) xlapp.CalculateUntilAsyncQueriesDone() xlbook.Save() xlbook.Close() del xlbook finally: # 确保无论是否出错都关闭Excel进程 xlapp.Quit() del xlapp
完整修正后的代码
import time import schedule import win32com.client as win32 import os OD = 'C:/DirectoryString/' # 子目录定义 Dir1 = 'STR - Doc/Mer Reps/' Dir2 = 'UK & IE ST - ICS/DB/' Dir3 = 'UK & IE ST - Docs/DB/2024/' Dir4 = 'UK & IE RDF - Docs/Rep/DB/Aut/' Dir5 = 'STR - Doc/RMS/' Dir6 = 'STR - Doc/Int DB/' # 使用os.path.join拼接路径,避免分隔符错误 directory_1 = os.path.join(OD, Dir1) directory_2 = os.path.join(OD, Dir2) directory_3 = os.path.join(OD, Dir3) directory_4 = os.path.join(OD, Dir4) directory_5 = os.path.join(OD, Dir5) directory_6 = os.path.join(OD, Dir6) def excel_update(directory): xlapp = win32.DispatchEx('Excel.Application') xlapp.DisplayAlerts = False xlapp.Visible = True try: for filename in os.listdir(directory): if filename.endswith(('.xlsx', '.xlsm')): file_path = os.path.join(directory, filename) print(f"处理文件:{file_path}") xlbook = xlapp.Workbooks.Open(file_path) xlbook.RefreshAll() xlapp.CalculateUntilAsyncQueriesDone() xlbook.Save() xlbook.Close() del xlbook finally: xlapp.Quit() del xlapp # 正确注册定时任务 schedule.every(30).minutes.do(excel_update, directory_2) while True: schedule.run_pending() time.sleep(1)
额外说明
- 用
os.path.join()拼接路径,避免手动拼接时出现跨平台路径分隔符错误 - 添加
try...finally块,确保Excel实例无论是否报错都会被关闭,防止后台残留Excel进程 - 调用
xlapp.CalculateUntilAsyncQueriesDone()等待异步刷新完成,避免数据未更新就保存
内容的提问来源于stack exchange,提问作者MBrann
相关产品推荐
相关产品推荐

