保存变量的Python蓝图Flask
我开发了一个应用程序,可以通过互联网控制一些设备,使用的是Flask和蓝图,运行在树莓派上。在客户端,我有一个安卓应用,它发送HTTP请求,而树莓派上的Flask应用则作为服务器进行响应。我有一个场景是控制风扇,通过设置一个引脚来进行PWM(脉宽调制),然后改变它的占空比来控制风扇的转速。在我改变风扇速度后,应用会返回一个JSON消息,里面包含当前的占空比以及风扇是否在转动(我知道转动的部分没什么用 :))。问题是,我无法把占空比保存在一个变量里,因为每次我重新调用那个只报告状态的函数时,它都会重置(就是那个带有“/”路由的函数)。我想不出一个简单快速的方法来做到这一点,而不想使用文件来保存,如果可以的话,我希望尽量避免用文件。
这是主应用的代码,里面注册了控制风扇的蓝图。
from flask import Flask
from scen3 import scen3_api
from scen2 import scen2_api
app = Flask(__name__)
app.register_blueprint(scen3_api, url_prefix='/scenariu/3')
app.register_blueprint(scen2_api, url_prefix='/scenariu/2')
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80, debug=True)
这是第二个脚本的代码,里面包含了场景2的内容。基本上,它在设置引脚后有两个函数,一个是在“/”路由上返回占空比和转动状态,另一个是在“/PWMValue/”路由上根据参数改变PWM的值。
import RPi.GPIO as GPIO
from flask import Flask, render_template, request, jsonify, Blueprint
scen2_api= Blueprint('scen2_api', __name__)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, GPIO.HIGH)
GPIO.setup(16,GPIO.OUT)
GPIO.output(16,GPIO.LOW)
dutyCycle=0
spin=0
p = GPIO.PWM(12, 500)
p.start(float(dutyCycle))
#spin=0
@scen2_api.route("/")
def main():
spin=0
if dutyCycle != 0.0:
spin=1
return jsonify(state=str(spin),pwmvalue=str(dutyCycle))
@scen2_api.route("/PWMValue/<action>")
def action( action):
dutyCycle=float(action)
p.ChangeDutyCycle(float(dutyCycle))
return jsonify(state=str(spin),pwmvalue=str(dutyCycle))
每次我调用报告函数时,它都返回0的占空比和转动状态。我该如何解决这个问题,同时又希望它的行为保持不变,最好是不使用文件?谢谢 :)
2 个回答
你可能遇到了作用域的问题,也可能有缩进的问题……但你的问题主要是和作用域有关:
在 action(action)
这个函数里,你设置了一个叫 dutyCycle
的变量,这个变量只在 action
函数内部有效。我想你是希望改变一个“全局”的变量。为了更好地理解发生了什么,看看下面的内容:
>>> g = 34
>>> g
34
>>> def f(n):
... g = n
... print g
...
>>> f(3)
3
>>> g
34
>>>
f
只改变了它自己内部的 g
,并没有改变你期待的全局变量。你可以看看这篇博客,了解一下 Python 的执行模型。你可以直接看“块和作用域”那一部分,但我建议你把整篇都读一下。
回到你的代码:
- 其实没有必要使用全局变量
dutyCycle
和spin
- 把所有的 GPIO 初始化放到一个单独的函数里
spin
和 dutyCycle
是在 main
和 action
函数里面的局部变量。你在这些函数里定义的所有变量默认都是局部的。如果你想让 Python 把它们当作全局变量来使用,就需要用 global
这个关键词来告诉它。
@scen2_api.route("/")
def main():
global spin
spin=0
if dutyCycle != 0.0:
spin=1
return jsonify(state=str(spin), pwmvalue=str(dutyCycle))
@scen2_api.route("/PWMValue/<action>")
def action( action):
global dutyCycle
dutyCycle = float(action)
p.ChangeDutyCycle(float(dutyCycle))
return jsonify(state=str(spin), pwmvalue=str(dutyCycle))