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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:18:27