2015-12-02 8 views
5

में सीधे इंतजार कैसेMixinig async संदर्भ प्रबंधक और asyncio

async with api.open() as o: 
    ... 

और

o = await api.open() 

मिश्रण करने के लिए एक समारोह में?

के बाद से पहली __aenter__ और __aexit__ के साथ वस्तु की आवश्यकता होती है, लेकिन दूसरी __await__, जो await बिना जनरेटर होना चाहिए की आवश्यकता है।

मेरे प्रयास किया गया था:

def AsyncContext(aenter, aexit): 

    class AsyncContextClass: 

     async def __aenter__(self): 

      return await aenter() 

     async def __aexit__(self, *args): 

      return await aexit(*args) 

     def __await__(self): 

      return (yield from aenter()) 

    return AsyncContextClass() 

लेकिन यह __await__ साथ अगर aenterasync def (TypeError: cannot 'yield from' a coroutine object in a non-coroutine generator) के साथ परिभाषित विफल रहता है।

यह @asyncio.coroutine सजावट aenter के लिए सजावट के साथ ठीक काम करता है, लेकिन यह «गंदा» है।

उत्तर

10

आप अपने वर्ग के __await__ से लौट सकते हैं __aenter__ के __await__:

# vim: tabstop=4 expandtab 

import asyncio 

class Test(object): 

    async def __aenter__(self): 
     print("enter") 

    async def __aexit__(self, *args): 
     print("exit") 

    def __await__(self): 
     return self.__aenter__().__await__() 

async def run(): 
    async with Test(): 
     print("hello") 

    await Test() 

loop = asyncio.get_event_loop() 
loop.run_until_complete(run()) 
loop.close() 

आउटपुट:

enter 
hello 
exit 
enter 
संबंधित मुद्दे