2017-11-28 5 views
-2

の代入の前に参照されたローカル変数私は上記のコードでは、私はのWebSocketを開いていると私は、新しいメッセージを受信するたびに、その後、on_message()関数が呼び出されエラー:パイソン

run_once1 = True 
run_once2 = False 

def on_message(ws, message): 

    if 'Temp' in message: 
     if run_once1 is True: 
      #Run this code once 
      print("Temp is present") 
      run_once1 = False 
      run_once2 = True 

    else: 
     if run_once2 is True: 
      #Run this code once 
      print("Temp is not present")  
      run_once1 = True 
      run_once2 = False  

def on_error(ws, error): 
    print(error) 

def on_close(ws): 
    print("CLOSE ") 

def on_open(ws): 
    print("OPEN") 
    msg = "<MESSAGE>" 
    ws.send(msg) 

ws = websocket.WebSocketApp(URL, on_message= on_message, on_error=on_error, on_close=on_close) 
ws.on_open = on_open 
ws.run_forever() 

のpythonのWebSocketクライアントコードを持っています。この関数の中で、メッセージにタグTempがあります。それが存在する場合、私はそれを印刷して一度だけ実行したいだけです。次にTempが存在しないときは、印刷してそのコードを1回だけ実行したいと思います。しかし、上記のコードはエラーを与える:それは私に、このエラーを与えないように、私はこれらの変数を記述する必要があります

error from callback <function on_message at 0x000001D35366D840>: local variable 'run_once1' referenced before assignment

error from callback <function on_message at 0x000001D35366D840>: local variable 'run_once2' referenced before assignment

おかげであなたはその関数のグローバルとして宣言する必要がある関数内のグローバル変数に代入するために

答えて

1

。たとえば、次のようになります。

def on_message(ws, message): 
    global run_once1 
    global run_once2 

    # remainder of function as before 
0

変数は関数のスコープから宣言されます。あなたの関数は、インデントから宣言された変数を表示しません(関数内で宣言された変数も、同じ名前の変数の値を外部に変更しません)。

これらの変数を関数引数、例えば:。

run_once1 = True 
run_once2 = False 

def on_message(ws, message, run_once1, run_once2): 

    if 'Temp' in message: 
     if run_once1 is True: 
      #Run this code once 
      print("Temp is present") 
      run_once1 = False 
      run_once2 = True 

    else: 
     if run_once2 is True: 
      #Run this code once 
      print("Temp is not present")  
      run_once1 = True 
      run_once2 = False  
    return run_once1, run_once2 

run_once1, run_once2 = on_message (ws, message, run_once1=run_once1, run_once2=run_once2 

しかし、あなたの場合には、それはあなたが状態を維持するために、そして、この関数の直接呼び出しをしたいので、私はクラスとして「ON_MESSAGE」を書くと、動作しません。

class OnMessage(): 
    def __init__(self): 
     self.run_once1 = True 
     self.run_once2 = False 

    def __call__(self, ws, message): 
     if 'Temp' in message: 
      if self.run_once1 is True: 
       #Run this code once 
       print("Temp is present") 
       self.run_once1 = False 
       self.run_once2 = True 

     else: 
      if self.run_once2 is True: 
       #Run this code once 
       print("Temp is not present")  
       self.run_once1 = True 
       self.run_once2 = False 

on_message = OnMessage() 

def on_error(ws, error): 
    print(error) 

def on_close(ws): 
    print("CLOSE ") 

def on_open(ws): 
    print("OPEN") 
    msg = "<MESSAGE>" 
    ws.send(msg) 

ws = websocket.WebSocketApp(URL, on_message= on_message, on_error=on_error, on_close=on_close) 
ws.on_open = on_open 
ws.run_forever()