Python/Pandas:log_add_game函数更新全局DataFrame异常求助
Pandas全局DataFrame更新异常问题
问题描述
我是Python/Pandas新手,编写log_add_game()函数向全局DataFrame df_log_game 添加记录(仅保留time列)。首次运行脚本一切正常,但后续多次调用函数时,函数内显示记录已新增,可全局的df_log_game始终只有初始1条记录。重新运行函数定义代码后,再次调用又能正常更新全局变量。
代码示例
import pandas as pd from datetime import datetime as dt df_log_game = pd.DataFrame(columns=['time']) # 创建日志DataFrame def log_add_game(): global df_log_game print("df_log_game") print(df_log_game) print('-----------------------') new_log = { 'time': dt.now() } print("new_log") print(new_log) print('-----------------------') df_log_game = df_log_game.append(new_log, ignore_index=True) print("new df_log_game") print(df_log_game) print('-----------------------') log_add_game() print(df_log_game)
运行现象
- 首次运行脚本后,
df_log_game包含1条记录,符合预期。 - 再次调用
log_add_game(),函数内输出显示已新增第2条记录:
df_log_game time 0 2022-07-24 00:32:34.312267 ----------------------- new_log {'time': datetime.datetime(2022, 7, 24, 0, 37, 42, 592565)} ----------------------- new df_log_game time 0 2022-07-24 00:32:34.312267 1 2022-07-24 00:37:42.592565 -----------------------
- 但全局环境下查看
df_log_game仍只有初始记录:
print(df_log_game) time 0 2022-07-24 00:32:34.312267
原因分析
这是交互式环境(如Jupyter Notebook/IPython)的变量绑定特性导致的:
- 首次运行脚本时,
df_log_game被创建为全局变量,同时log_add_game()函数被定义,函数内的global df_log_game会绑定此时的全局df_log_game对象。 - 若后续不小心重新运行了创建
df_log_game的代码行(df_log_game = pd.DataFrame(columns=['time'])),会生成一个全新的DataFrame对象覆盖全局变量,但之前定义的log_add_game()函数里的global仍指向旧的DataFrame对象。 - 此时调用函数,修改的是旧对象,而全局环境中查看的是新对象,所以看不到更新;重新运行函数定义后,
global会重新绑定当前的全局df_log_game,修改操作才会生效。
另外说明:Pandas的append()方法返回新的DataFrame,而非原地修改,代码中df_log_game = df_log_game.append(...)的写法本身是正确的,问题核心在于全局变量的绑定错位。
解决办法
- 避免在交互式环境中重复运行创建
df_log_game的代码,确保全局变量始终指向同一个DataFrame对象。 - 更推荐的方案是用类封装日志功能,彻底避免全局变量带来的绑定问题:
import pandas as pd from datetime import datetime as dt class GameLog: def __init__(self): self.df_log = pd.DataFrame(columns=['time']) def add_game(self): new_record = {'time': dt.now()} self.df_log = self.df_log.append(new_record, ignore_index=True) # 可选:返回更新后的DataFrame return self.df_log # 使用示例 game_log = GameLog() game_log.add_game() print(game_log.df_log) game_log.add_game() print(game_log.df_log)
内容的提问来源于stack exchange,提问作者moony
相关产品推荐
相关产品推荐

