2017-04-04 54 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