2014-05-02 69 views
1

假設我得到了以下的設置(簡化):如何在python中輕鬆處理動態裝飾器?

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) 

我現在想兩個功能test_connectOnetest_ConnectTwo移動到單獨的模塊。我正在考慮爲每個模塊創建兩個類並使其功能如此靜態:

class ModuleOne (object): 

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

但是由於這種情況,我遇到了麻煩。我現在必須以某種方式將socketio對象放入類中(例如,通過與靜態變量組合的簡單設置器)。但是我猜想socketio.on()註釋會在模塊ModuleOne被導入別的地方之前觸發,然後我可以設置任何變量。

我該如何解決這種情況? (我打開它進入一個完全不同的方向太的解決方案。)

+0

沒有,裝飾都擡起頭來全局時也用作方法裝飾器;查找裝飾器是否正在定義'test_One()'方法。我會*不*把你的函數放在類中,即使是靜態方法。它根本沒有額外的好處,只會使你的代碼複雜化。將視圖改爲實際單獨的模塊文件。 –

+0

但是,如何將socketio對象以乾淨的方式放入這些模塊? – ben

+0

您可以導入它;在你的主模塊中,在'socketio'對象被定義之後導入你的模塊和視圖*,然後帶有視圖的模塊就可以使用'from mainmodule import socketio'。 –

回答

3

你有兩個選擇:

  1. 導入socketio對象爲你把意見在單獨的模塊,只要你然後導入該模塊創建socketio對象的事情工作。所以你main模塊中您有:

    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) 
    

    socket_views.py您有:

    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') 
    

    見瓶文檔的Larger Application章;特別是「循環進口」部分。

  2. 應用@socketio.on()裝飾'手動'; @expression語法只是將函數調用到函數中的語法糖。由於@socketio.on()裝飾唯一寄存器你可以簡單地把你的意見,定期,非裝飾功能的獨立的模塊中,然後用導入後註冊它們:

    from socket_views import test_connectOne, test_connectTwo 
    
    socketio.on('connect', namespace='/namespaceOne')(test_connectOne) 
    socketio.on('connect', namespace='/namespaceTwo')(test_connectTwo)