2017-04-04 63 views
1

我想提出的異步功能的上下文管理器每次調用一個函數執行「移動」到另一個上下文執行上下文動作異步上下文管理器開關

例如

import os 
import asyncio 

class AsyncContextChangeDir: 
    def __init__(self, newdir): 
     self.curdir = os.getcwd() 
     self.newdir = newdir 

    async def __aenter__(self): 
     os.chdir(self.newdir) 

    async def __aexit__(self, exc_type, exc_value, traceback): 
     os.chdir(self.curdir) 

async def workon_mypath(): 
    async with AsyncContextChangeDir("/tmp"): 
     print("working in /tmp context manager, cwd:" + os.getcwd()) # /mypath 
     await asyncio.sleep(100) 
     print("working in /tmp context manager, cwd:" + os.getcwd()) # ??? 

async def workon_someotherpath(): 
    await asyncio.sleep(10) 
    os.chdir("/home") 
    print("working in other context cwd:" + os.getcwd()) 


loop = asyncio.get_event_loop() 
loop.run_until_complete(asyncio.gather(
    workon_mypath(), 
    workon_someotherpath())) 

我想第二打印打印/mypath,明明每次都恢復到以前的工作目錄執行「切換」到另一個上下文

什麼是做到這一點的最好方法是什麼?

回答

0

與您可能期望的名稱相反,作爲概念的上下文管理器與上下文切換沒有任何關係。

無論是常規上下文管理器還是異步上下文管理器都不知道事件循環「上下文切換」。上下文管理器無法檢測到事件循環將開始運行另一個協程,並且上下文管理器無法在發生這種情況時執行代碼。

+0

謝謝你的回覆。有沒有其他的結構可以達到理想的行爲? 協程有任何方法來檢測事件循環是否會開始運行另一個協程? – Recursing

+0

@Recursing:你可以通過修改事件循環,或者通過實現一個特殊的協程來執行它,每次它產生或恢復時執行已註冊的回調函數,但是'async'語法不足以實現它,而且它是無論如何,這是一種危險的,容易出錯的設計 – user2357112

+0

那麼沒有標準的方法來檢測「上下文切換」?我很驚訝它不被認爲是一個有用的功能 – Recursing