Python Telegram Bot跨文件导入运行时变量被重置问题求解
问题原因
两个脚本是独立运行的进程,内存空间完全隔离。你通过import main导入的只是当前进程重新加载的main模块初始值,完全拿不到后台持续运行的main.py进程里修改后的运行时变量。
可行解决方案
方案1:持久化存储共享数据(最快捷适配你现有逻辑)
用JSON文件作为中间存储,main.py修改变量后写入文件,message_sender.py直接读文件拿数据,不需要import main。
步骤1:新增公共配置文件common.py,放两边都要用到的公共内容
# common.py BOT_TOKEN = "<MY-BOT-TOKEN>" message_list = { '1': 'First day', '2': 'Second day' }
步骤2:修改main.py,读写JSON文件同步变量
from datetime import timedelta, datetime, timezone import time import telebot import json import os from common import BOT_TOKEN, message_list bot = telebot.TeleBot(BOT_TOKEN) CONFIG_PATH = "runtime_config.json" # 初始化变量,优先读本地配置 user_id = 1 date_of_start = 0 if os.path.exists(CONFIG_PATH): with open(CONFIG_PATH, "r", encoding="utf-8") as f: config = json.load(f) user_id = config.get("user_id", 1) date_of_start = config.get("date_of_start", 0) # 变量更新后同步写入配置的工具函数 def save_config(): with open(CONFIG_PATH, "w", encoding="utf-8") as f: json.dump({"user_id": user_id, "date_of_start": date_of_start}, f) @bot.message_handler(commands=['start']) def start_every_day_message(message): global user_id, date_of_start user_id = message.from_user.id date_of_start = int(datetime.today().day) save_config() # 修改变量后存文件 bot.send_message(user_id, 'You start every day spamming') @bot.message_handler(commands=['stop']) def stop_every_day_message(message): global date_of_start bot.send_message(user_id, "You stop your every day spamming") date_of_start = 0 save_config() # 修改变量后存文件 print(date_of_start, user_id) if __name__ == '__main__': try: bot.polling(none_stop=True) except Exception as e: print(e) time.sleep(15)
步骤3:修改message_sender.py,直接读配置文件拿数据
import json import telebot from datetime import datetime from common import BOT_TOKEN, message_list # 读配置 with open("runtime_config.json", "r", encoding="utf-8") as f: config = json.load(f) user_id = config["user_id"] date_of_start = config["date_of_start"] bot = telebot.TeleBot(BOT_TOKEN) this_day = int(datetime.today().day) current_diferience = 0 # 后面的日期计算逻辑保持不变即可 if this_day - date_of_start < 0: month = int(datetime.today().month) -1 year = int(datetime.today().year) if month in [0,1,3,5,7,8,10]: current_diferience = this_day - date_of_start + 31 elif month == 2: current_diferience = this_day - date_of_start + 29 if year %4 ==0 else 28 else: current_diferience = this_day - date_of_start + 30 else: current_diferience = this_day - date_of_start if current_diferience <= 30: bot.send_message(user_id, message_list.get(str(current_diferience), "今日无预设消息")) else: bot.send_message(user_id, "First day")
方案2:定时任务集成到main.py(更简洁,无需跨进程)
直接在main.py里加定时任务,不用单独跑message_sender.py,所有变量同进程共享,不需要额外存文件。
需要先安装依赖:pip install apscheduler
修改后的main.py示例:
from datetime import timedelta, datetime, timezone import time import telebot from apscheduler.schedulers.background import BackgroundScheduler from common import BOT_TOKEN, message_list bot = telebot.TeleBot(BOT_TOKEN) user_id=1 date_of_start=0 # 每日发送消息的逻辑,直接放在main里 def send_daily_message(): if date_of_start == 0: # 没有启动的用户就不发 return this_day = int(datetime.today().day) current_diferience = 0 if this_day - date_of_start < 0: month = int(datetime.today().month) -1 year = int(datetime.today().year) if month in [0,1,3,5,7,8,10]: current_diferience = this_day - date_of_start + 31 elif month == 2: current_diferience = this_day - date_of_start + 29 if year %4 ==0 else 28 else: current_diferience = this_day - date_of_start + 30 else: current_diferience = this_day - date_of_start if current_diferience <= 30: bot.send_message(user_id, message_list.get(str(current_diferience), "今日无预设消息")) else: bot.send_message(user_id, "First day") @bot.message_handler(commands=['start']) def start_every_day_message(message): global user_id user_id = message.from_user.id global date_of_start date_of_start = int(datetime.today().day) bot.send_message(user_id, 'You start every day spamming') @bot.message_handler(commands=['stop']) def stop_every_day_message(message): bot.send_message(user_id, "You stop your every day spamming") global date_of_start print(date_of_start, user_id) date_of_start = 0 if __name__ == '__main__': # 启动后台定时任务,每天8点发消息,时间可以自己改 scheduler = BackgroundScheduler() scheduler.add_job(send_daily_message, 'cron', hour=8, minute=0) scheduler.start() try: bot.polling(none_stop=True) except Exception as e: print(e) time.sleep(15)
方案3:多用户扩展可选
如果后续需要支持多个用户同时使用,推荐用SQLite轻量数据库存储每个用户的user_id、启动时间等数据,读写更安全,也支持多进程访问。
注意
你当前的代码只支持单个用户使用,如果要支持多用户,不要用全局变量存单个user_id,要改成存储用户ID和对应启动时间的映射结构,配合JSON/SQLite存储即可。
内容的提问来源于stack exchange,提问作者Mr. Shiz
相关产品推荐
相关产品推荐

