在Python脚本中调用另一个脚本时程序异常退出的问题排查
问题分析与解决方案
问题根源
- 模块导入时自动执行代码:
output.py的顶层代码直接调用了run()函数,当main.py导入output模块时,这个run()会自动执行,导致程序提前进入死循环,阻塞main.py的后续逻辑(用户输入、停止信号写入)。 - 主线程阻塞:即使移除顶层的
run()调用,main.py直接调用run()后,run()的死循环会占据主线程,导致main.py无法执行写入bridge.txt的循环,output.py的run()永远检测不到停止信号,或因初始文件状态触发提前退出。
修改后的代码
output.py
import os from time import sleep from pynput.keyboard import Controller keyboard = Controller() def run(): global keyboard sleep(10) keyboard = Controller() count = 0 while True: if os.path.exists('bridge.txt'): with open('bridge.txt', 'r') as file: content = file.readlines() for line in content: # 去除换行符避免判断错误 if line.strip() == '1': exit(0) if count == 1: press_key('w') elif count == 2: press_key('a') elif count == 3: press_key('s') elif count == 4: press_key('d') elif count == 10: count = 0 press_key('q') count += 1 sleep(0.1) def press_key(key): keyboard.press(key) sleep(0.5) keyboard.release(key) # 移除顶层的run()调用,仅在主动调用时执行
main.py
import os import threading from output import run import keyboard from time import sleep print('Start afk program? (Y/N)') cmd = str.lower(input('> ')) if cmd == 'y': print('Use X to Stop') print('Starting in 10 seconds...') # 用线程启动AFK逻辑,避免阻塞主线程 afk_thread = threading.Thread(target=run) afk_thread.daemon = True # 主线程退出时自动终止子线程 afk_thread.start() while True: # 简化停止信号判断 x = '1' if keyboard.is_pressed('x') else '0' if os.path.exists('bridge.txt'): with open('bridge.txt', 'w') as file: file.write(x) # with语句自动关闭文件,无需手动调用close() else: print('bridge.txt not found') exit(1) if x == '1': print('exit key pressed') exit(0) sleep(0.1)
关键改进点
- 移除自动执行的run():确保
output.py的run()仅在main.py主动调用时执行,避免导入模块时的意外阻塞。 - 多线程并行执行:用子线程运行AFK逻辑,主线程专注处理键盘输入和停止信号写入,保证两个核心循环同时工作。
- 优化文件操作:去掉多余的
file.close()(with语句会自动管理文件生命周期),增加strip()处理换行符,避免读取文件时的判断错误。
内容的提问来源于stack exchange,提问作者Intergalactic Carpet
相关产品推荐
相关产品推荐

