如何避免使用全局变量? (python-flask-socketio应用) [英] How can I avoid to use global variables? (python - flask-socketio app)
问题描述
我试图弄清楚如何在我的应用程序中不使用全局变量,但是我什么也没想到.
I'm trying to figure out how to not use global variables for my application but I can't think of anything else.
我实际上是在Flask-SocketIO模块的帮助下对Web界面进行编码,以与音乐播放器进行实时交互.
I'm actually coding a web interface with the help of the Flask-SocketIO module to interact in real time with a music player.
这是我的包含播放功能的代码的片段(我想我只需要一个示例,然后就可以将其用于所有其他功能):
This is a snippet of my code containing the play function (I think I only need one example and then I can adapt it for all the other functions):
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
socketio = SocketIO(app)
isPlaying = False #This is the variable that I would like to avoid making global
@socketio.on('request_play')
def cycle_play():
global isPlaying
if isPlaying == True:
socketio.emit('pause', broadcast=True)
isPlaying = False
else:
socketio.emit('play', broadcast=True)
isPlaying = True
if __name__ == '__main__':
socketio.run(app, port=5001)
这只是代码的简化版本,但我认为足以理解我要完成的工作.
This is only a stripped down version of the code but I think it's enough to understand what I'm trying to accomplish.
我还需要从其他函数访问该变量,并且需要对歌曲名称,持续时间和当前时间进行相同的操作.
I need to access that variable also from other functions and I need to do the same with the song name, duration and current time.
预先感谢您的帮助,如果我的英语不太清楚,请谅解.
Thanks in advance for the help and sorry if my English is not clear.
这是我使用的解决方案:
Here is the solution that I used:
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
socketio = SocketIO(app)
class Player():
def __init__(self):
self.isPlaying = False
def cycle_play(self):
if self.isPlaying == True:
socketio.emit('pause', broadcast=True)
self.isPlaying = False
else:
socketio.emit('play', broadcast=True)
self.isPlaying = True
if __name__ == '__main__':
player = Player()
socketio.on('request_play')(player.cycle_play) #this is the decorator
socketio.run(app, port=5001)
推荐答案
建议自己的解决方案是定义一个类,该类封装了状态变量及其对状态变量的响应.由于我不熟悉Flask-SocketIO
的详细信息,因此请将其视为pseduocode,而不是将其粘贴到工作程序中.
The solution that suggests itself is to define a class which encapsulates both the state variable and the responses to its change. Since I'm not familiar with the details of Flask-SocketIO
please treat this as pseduocode rather than something to be pasted in to a working program.
class PlayControl:
def __init__(self, initial):
self.is_playing = initial
def cycle_play(self):
if self.is_playing:
socketio.emit('pause', broadcast=True)
self.is_playing = False
else:
socketio.emit('play', broadcast=True)
self.is_playing = True
然后,您将创建此类的实例,并将该实例的cycle_play
方法传递给与装饰原始函数相同的函数.由于此行为是动态的,因此不适合在方法定义上使用装饰器.
You would then create an instance of this class, and pass the instance's cycle_play
method to the same function you decorated your original function with. Because this behaviour is dynamic it's not appropriate to use a decorator on the method definition.
control = PlayControl(False)
socketio.on('request_play')(control.cycle_play)
要减少程序代码的数量,您甚至可以定义一个类,该类将要调用的函数和将值作为参数发出,进一步推广该概念,以使代码更简洁,更少样板.
To reduce the amount of program code you could even define a class that took the functions to call and the values to emit as arguments, generalising the concept further to make code more concise and with less boilerplate.
这篇关于如何避免使用全局变量? (python-flask-socketio应用)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!