2017-07-17 8 views
1

Ich versuche, etwas asynchrones Messaging für ein Controller-Projekt, das ich tue, zu tun, und das Ziel der folgenden Funktion ist, einen Rückruf an einen Appjar app.registerEvent Anruf, der die Aktualisierung der Statusbereich der Motorsteuerung UI.Wie man Closures mit asyncio behandelt

def motorStatusMonitor(loop: aio.AbstractEventLoop, app: aj.appjar.gui, Messenger: cmd.PyCmdMessenger.CmdMessenger)-> Callable: 
    async def getStatus(aFuture): 
     nonlocal Messenger 
     nonlocal app 
     # Ask for the current status of the motor 
     t = await Control.sendCommand(Messenger, "Status") 
     d = {t[1][0]: t[1][1], t[1][2]: t[1][3]} # parse the response 
     def statusChanger(): # need a closure to write to the app when called 
      nonlocal d # use the message from above 
      nonlocal app # use the app passed with motorStatusMonitor 
      app.openTab("Main", "Control") 
      app.openLabelFrame("Status") 
      app.setLabel("motorStatus", f"Motor A: \t\t {get('A', d, '???')}\nMotor B: \t\t {get('B', d, '???')}") # Print the status of the motors to the app 
     aFuture.set_result(statusChanger) 

    future = aio.Future() 
    aio.ensure_future(getStatus(future)) 
    loop.run_until_complete(future) 
    return future.result() 

Dies ist jedoch nicht funktioniert, als wenn ich app.registerEvent(motorStatusMonitor(event_loop, app, Messenger)) tun es hängt nur für immer.

Wie sollte ich eigentlich async hier implementieren?

Der vollständige Code für alles ist unter Github. Diese

+0

Wie würden Sie erwarten, dass andere Ihnen helfen, wenn es keinen Code gibt, der anzeigt, was Sie tun? – Ding

+0

Ich habe versehentlich einreichen, bevor ich die Frage gestellt habe, es war ein Fehler meinerseits. – nick5435

+0

Was versuchen Sie eigentlich zu erreichen? Weil der Verschluss kein Problem ist. Zumindest könnten Sie Ihren Code so umarbeiten, dass er keine Schließung verwendet, sondern stattdessen eine globale "App" verwendet. Ich sage nicht, dass die Schließung nicht der richtige Ansatz ist (auch wenn es in Python nicht sehr beliebt ist). Ich sage, dass Sie vielleicht das XY-Problem https://meta.stackexchange.com/questions/66377/what-is verfolgen Das-xy-Problem. Versuchen Sie zu erweitern, was Sie versuchen, bitte zu erreichen. – amirouche

Antwort

0

:

loop.run_until_complete(future) 

Wartet die für die Zukunft zu vervollständigen, die es nie.

Auch Sie müssen nicht future.result() anrufen, sondern stattdessen etwas wie await future, die das Ergebnis zurückgeben wird.

+0

Also am Ende meiner Funktion, in der ich die Schließung zurückgeben muss, ich nur "Rückkehr erwarte Zukunft", und werde den Aufruf von "loop.run_until_complete" loswerden? – nick5435

+0

Ich glaube auch nicht, dass ich "erwarten" hier verwenden kann, da ich keine Coro erstelle, muss diese Funktion speziell synchron sein. – nick5435