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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:23:23