Flask设置FLASK_APP为app.py却优先运行PythonApplication1且导入报错怎么办
问题原因
- 导入模块时自动执行顶层代码:Python导入任意模块时,会自动执行该模块内所有无缩进的顶层代码。你的PythonApplication1.py里的音量计算、sd.Stream启动逻辑都属于顶层代码,只要执行
import PythonApplication1语句就会立刻运行,不需要主动调用函数,所以会在app.py完全加载前就先执行。 - 变量作用域错误:PythonApplication1.py里的
volume_norm是print_sound函数内的局部变量,你在函数外直接写a = int(volume_norm)属于访问不存在的全局变量,会直接抛出错误,这就是ImportError的直接诱因。 - 循环导入问题:utils目录下的
__init__.py里写了import app,而app.py又间接依赖utils模块的内容,会形成循环导入链,进一步触发导入错误。
解决步骤
- 修复PythonApplication1.py的代码,把所有执行逻辑封装,避免导入时自动运行,同时修复变量作用域问题:
import sounddevice as sd from numpy import linalg as LA import numpy as np duration = 20 cnt = 0 check_cnt = 0 def print_sound(indata, outdata, frames, time, status): global cnt, check_cnt volume_norm = np.linalg.norm(indata)*10 a = int(volume_norm) if a <= 28: cnt = cnt + 1 if cnt == 300: check_cnt += 1 print ("You are too quiet!","Now you're checked", check_cnt, "times") cnt = 0 # 仅当直接运行该文件时才执行声音检测逻辑,导入时不执行 if __name__ == '__main__': with sd.Stream(callback=print_sound): sd.sleep(duration * 1000)
- 修正utils目录下的
__init__.py,删除import app这一行,避免循环导入。 - 如果需要在Flask服务运行的同时启动声音检测,不要直接在app.py的顶层导入后运行,要改用独立线程启动,避免阻塞Flask主线程,修改app.py的对应逻辑:
from flask import Flask, render_template, Response from flask_bootstrap import Bootstrap from camera import VideoCamera import pymysql import PythonApplication1 as py1 import threading app = Flask(__name__) Bootstrap(app) # 启动声音检测的独立线程 def run_sound_detect(): with py1.sd.Stream(callback=py1.print_sound): py1.sd.sleep(py1.duration * 1000) if __name__ == '__main__': # 先启动声音检测线程 threading.Thread(target=run_sound_detect, daemon=True).start() # 再启动Flask服务 app.run(host='127.0.0.1',port=5000, debug=True)
内容的提问来源于stack exchange,提问作者Juliana Jang
相关产品推荐
相关产品推荐

