Вопрос

Suppose I got the following setup (simplified):

from flask import Flask
from flask.ext.socketio import SocketIO, emit, send

app = Flask(__name__)
socketio = SocketIO(app)

@socketio.on('connect', namespace='/namespaceOne')
def test_connectOne():
    print('new connection')

@socketio.on('connect', namespace='/namespaceTwo')
def test_connectTwo():
    print('new connection')

if __name__ == '__main__':
socketio.run(app)

I would now like to move the two functions test_connectOne and test_ConnectTwo into separate modules. I was thinking about creating two classes for each module and making the functions static like so:

class ModuleOne (object):

    @staticmethod
    @socketio.on('connect', namespace='/namespaceOne')
    def test_One():
        print('new connection')

But with this I'm running into trouble. I would now have to somehow get the socketio object into the class (e.g. by a simple setter in combination with a static variable). But I guess the annotation socketio.on() will trigger right when the module ModuleOne is imported somewhere else before I can set any variables.

How can I solve this situation? (I'm open to solutions which go into a completely different directions too.)

Это было полезно?

Решение

You have two options:

  1. Import the socketio object into the separate module you put the views in. As long as you then import that module after creating the socketio object things work. So in your main module you have:

    from flask import Flask
    from flask.ext.socketio import SocketIO, emit, send
    
    app = Flask(__name__)
    socketio = SocketIO(app)
    
    import socket_views
    
    if __name__ == '__main__':
        socketio.run(app)
    

    and in socket_views.py you have:

    from main import socketio
    
    @socketio.on('connect', namespace='/namespaceOne')
    def test_connectOne():
        print('new connection')
    
    @socketio.on('connect', namespace='/namespaceTwo')
    def test_connectTwo():
        print('new connection')
    

    See the Larger Application chapter of the Flask documentation; specifically the Circular Imports section.

  2. Apply the @socketio.on() decorator 'manually'; the @expression syntax is just syntactic sugar to apply a callable to a function. Since the @socketio.on() decorator only registers you can simply put your views as regular, un-decorated functions in the separate module then register them after importing with:

    from socket_views import test_connectOne, test_connectTwo
    
    socketio.on('connect', namespace='/namespaceOne')(test_connectOne)
    socketio.on('connect', namespace='/namespaceTwo')(test_connectTwo)
    
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top