繁体   English   中英

如何避免使用全局变量? (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)

您可以使用用户会话来存储此类值。 您可以在此处阅读有关会话对象的更多信息: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的详细信息,因此请将此视为pseduocode,而不是将其粘贴到工作程序中。

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方法传递cycle_play装饰原始函数相同的函数。 由于此行为是动态的,因此不适合在方法定义上使用装饰器。

control = PlayControl(False)
socketio.on('request_play')(control.cycle_play)

为了减少程序代码的数量,您甚至可以定义一个以调用函数作为参数并将值作为参数发出的类,进一步推广该概念,以使代码更简洁,更少样板。

我的建议是使用类,并且在init方法内部仅使用self.isPlaying = False。 您始终可以从类中的所有函数中引用此变量。 举个例子:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM