如何避免使用全局变量? (python - flask-socketio 应用程序)
How can I avoid to use global variables? (python - flask-socketio app)
我想弄清楚如何在我的应用程序中不使用全局变量,但我想不出其他任何东西。
我实际上是在 Flask-SocketIO 模块的帮助下编写一个 Web 界面,以便与音乐播放器进行实时交互。
这是我的一段代码,其中包含播放功能(我想我只需要一个示例,然后我就可以将它用于所有其他功能):
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)
这只是代码的精简版,但我认为这足以理解我要完成的任务。
我还需要从其他函数访问该变量,我需要对歌曲名称、持续时间和当前时间执行相同的操作。
在此先感谢您的帮助,如果我的英语不清楚,请见谅。
这是我使用的解决方案:
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)
建议的解决方案是定义一个 class 来封装状态变量和对其变化的响应。由于我不熟悉 Flask-SocketIO
的细节,请将其视为伪代码,而不是将其粘贴到工作程序中。
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
然后您将创建此 class 的一个实例,并将该实例的 cycle_play
方法传递给您用来装饰原始函数的同一函数。因为这种行为是动态的,所以在方法定义上使用装饰器是不合适的。
control = PlayControl(False)
socketio.on('request_play')(control.cycle_play)
为了减少程序代码的数量,您甚至可以定义一个 class,将要调用的函数和要发出的值作为参数,进一步概括概念,使代码更简洁,样板更少。
我的建议是使用 class,在 init 方法中只使用 self.isPlaying = False。您始终可以从 class 中的所有函数引用此变量。
例如:
class PLAYER(object):
def __init__(self,other parameters):
self.isPlaying = False
#your cod
def cycle_play(self):
#global isPlaying
if self.isPlaying == True:
socketio.emit('pause', broadcast=True)
self.isPlaying = False
else:
socketio.emit('play', broadcast=True)
self.isPlaying = True
您可以使用用户会话来存储此类值。您可以在此处阅读有关会话对象的更多信息:flask.pocoo.org/docs/0.12/quickstart/#sessions。
from flask import session
@socketio.on('initialize')
def initialize(isPlaying):
session['isPlaying'] = isPlaying
@socketio.on('request_play')
def cycle_play():
# Note, it's good practice to use 'is' instead of '==' when comparing against builtin constants.
# PEP8 recommended way is to check for trueness rather than the value True, so you'd want to first assert that this variable can only be Boolean.
assert type(session['isPlaying']) is bool
if session['isPlaying']:
socketio.emit('pause', broadcast=True)
session['isPlaying'] = False
else:
socketio.emit('play', broadcast=True)
session['isPlaying'] = True
我想弄清楚如何在我的应用程序中不使用全局变量,但我想不出其他任何东西。
我实际上是在 Flask-SocketIO 模块的帮助下编写一个 Web 界面,以便与音乐播放器进行实时交互。
这是我的一段代码,其中包含播放功能(我想我只需要一个示例,然后我就可以将它用于所有其他功能):
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)
这只是代码的精简版,但我认为这足以理解我要完成的任务。
我还需要从其他函数访问该变量,我需要对歌曲名称、持续时间和当前时间执行相同的操作。
在此先感谢您的帮助,如果我的英语不清楚,请见谅。
这是我使用的解决方案:
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)
建议的解决方案是定义一个 class 来封装状态变量和对其变化的响应。由于我不熟悉 Flask-SocketIO
的细节,请将其视为伪代码,而不是将其粘贴到工作程序中。
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
然后您将创建此 class 的一个实例,并将该实例的 cycle_play
方法传递给您用来装饰原始函数的同一函数。因为这种行为是动态的,所以在方法定义上使用装饰器是不合适的。
control = PlayControl(False)
socketio.on('request_play')(control.cycle_play)
为了减少程序代码的数量,您甚至可以定义一个 class,将要调用的函数和要发出的值作为参数,进一步概括概念,使代码更简洁,样板更少。
我的建议是使用 class,在 init 方法中只使用 self.isPlaying = False。您始终可以从 class 中的所有函数引用此变量。 例如:
class PLAYER(object):
def __init__(self,other parameters):
self.isPlaying = False
#your cod
def cycle_play(self):
#global isPlaying
if self.isPlaying == True:
socketio.emit('pause', broadcast=True)
self.isPlaying = False
else:
socketio.emit('play', broadcast=True)
self.isPlaying = True
您可以使用用户会话来存储此类值。您可以在此处阅读有关会话对象的更多信息:flask.pocoo.org/docs/0.12/quickstart/#sessions。
from flask import session
@socketio.on('initialize')
def initialize(isPlaying):
session['isPlaying'] = isPlaying
@socketio.on('request_play')
def cycle_play():
# Note, it's good practice to use 'is' instead of '==' when comparing against builtin constants.
# PEP8 recommended way is to check for trueness rather than the value True, so you'd want to first assert that this variable can only be Boolean.
assert type(session['isPlaying']) is bool
if session['isPlaying']:
socketio.emit('pause', broadcast=True)
session['isPlaying'] = False
else:
socketio.emit('play', broadcast=True)
session['isPlaying'] = True