如何避免使用全局变量? (python-flask-socketio应用) [英] How can I avoid to use global variables? (python - flask-socketio app)

查看:180
本文介绍了如何避免使用全局变量? (python-flask-socketio应用)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚如何在我的应用程序中不使用全局变量,但是我什么也没想到.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆