while True循环后无法访问函数内df变量的解决方法
问题核心错误点
- 你在
dta_frame()内用global df声明了全局变量,但从未调用该函数,全局作用域中不存在df对象,访问时必然抛出NameError。 - 内层while循环条件逻辑写反:
d_time是循环启动时的当前时间,tgt是计算得到的未来2分钟对齐时间点,d_time > tgt恒为假,访问df的代码块永远不会执行。 - 同时混用
apscheduler和schedule两个独立定时框架,ttm()函数绑定的schedule装饰器没有对应的启动触发逻辑,根本不会按预期每2分钟运行。 - 现有测试数据中
df['Rank'].iloc[-1]固定为1,等于0的分支和else分支永远不会触发。
修复代码
不要用全局变量传值,直接通过函数返回值传递DataFrame,删掉冗余的调度库依赖,修正时间判断逻辑即可:
import datetime import pandas as pd import time import pause from apscheduler.schedulers.blocking import BlockingScheduler sched = BlockingScheduler(timezone='Asia/Kolkata') def fetch_latest_df(): """生成/拉取最新的DataFrame数据,直接返回对象,无需全局变量""" print("*** 加载最新df数据 ***", datetime.datetime.now().time()) data = { 'Name':['Jai', 'Princi', 'Gaurav', 'Anuj'], 'Age':[27, 24, 22, 32], 'Address':['Delhi', 'Kanpur', 'Allahabad', 'Kannauj'], 'Rank':[2, 4, 10, 1] } df = pd.DataFrame(data) print(df) return df def run_addn(): res = 25 * 25 print("执行addn逻辑,计算结果:", res, datetime.datetime.now().time()) def run_multi(): res = 10 * 50 print("执行multi逻辑,计算结果:", res, datetime.datetime.now().time()) @sched.scheduled_job('cron', day_of_week='mon-sat', hour=16, minute=12, second=0) def scheduled_job(): print('主定时任务启动....', datetime.datetime.now().time()) while True: # 每次循环先获取最新df df = fetch_latest_df() ts = time.time() # 计算下一个整2分钟的时间节点 target_time = datetime.datetime.fromtimestamp(ts + 118 - ts % 120) current_time = datetime.datetime.fromtimestamp(ts) # 修正判断条件:当前时间未到目标时间时执行分支判断 while current_time < target_time: last_rank_val = df['Rank'].iloc[-1] if last_rank_val == 1: run_addn() time.sleep(1) pause.until(target_time) break elif last_rank_val == 0: run_multi() time.sleep(1) pause.until(target_time) break else: print("无匹配执行分支", datetime.datetime.now().time()) time.sleep(1) pause.until(target_time) break if __name__ == "__main__": sched.start()
修改说明
- 移除冗余的
schedule库依赖,仅保留apscheduler实现定时触发,避免两套调度逻辑冲突。 - 废弃全局变量传值的写法,每次循环主动调用
fetch_latest_df()获取最新数据,通过函数返回值传递df对象,彻底解决作用域访问报错问题。 - 修正内层循环的时间判断条件,保证df值判断逻辑可以正常执行。
- 将数据获取、业务逻辑、调度逻辑拆分到独立函数,后续修改逻辑时不会互相影响。
内容的提问来源于stack exchange,提问作者B Sailoo
相关产品推荐
相关产品推荐

