2015-05-12 12 views
10

asyncio ile python chat bot framework geliştiriyorum. Ama ben PEP-492'u izliyorum ve yeni sözdizimi, async/await ve sonunda kabul edildi.3.4 ve 3.5 arasında python'da coroutine, backwords uyumluluğunu nasıl saklayabilirim?

async/await sözdizimini seviyorum ve kullanmak istiyorum. ama 3.4 geri bildirim uyumluluğu hakkında endişeleniyorum.

Kodumda yeni sözdizimi kullanırsam, biri 3.4'te kullanabilir mi?

Örneğin, ben py34 await sözdizimi yok, ben py35

loop = asyncio.get_event_loop() # I don't know it really needed in py35. 
bot = ChatBot(loop) 
asyncio.run_until_complete(bot.run()) 

bu kaynakla kullanabilirsiniz, bu gibi bazı kod,

import asyncio 

class ChatBot: 
    def __init__(self, loop): 
     self.loop = loop 

    async def connect(self): 
     self.reader, self.writer = await asyncio.open_connect(HOST, PORT, loop=self.loop) 

    async def read(): 
     return await self.reader.read() 

    async def run(self): 
     running = True 
     while running: 
      try: 
       await self.connect() 
       line = await self.read() 
       if not line: 
        continue 
       await self.parse(line) 
      except BotInternalError as e: 
       if e.stop: 
        running = False 
        break 
      except: 
       pass 

    async def parse(self, msg): 
     if msg.startswith('PING'): 
      self.pong() 
     elif msg.startswith('ERROR'): 
      self.error() 
     else: 
      await self.some_work(msg) 

    async def some_work(self, msg): 
     # some looooooooong works 
     self.send(msg) 

    def send(self, msg): 
     self.writer.write(msg) 

Daha yazma Ama. PyPI'da kaynak sınırlama olmaksızın, sürüm kısıtlaması olmadan yüklediysem ve birisi py34’e yüklediyse, iyi çalışır mı? Nasıl saklayabilirim?

cevap

13

Kodunuzda Python 3.4'ü desteklemeniz gerekirse, eski @asyncio.coroutine/yield from stil sözdizimini kullanmanız gerekir. 3.5 çalıştırmadan async/await sözdizimini desteklemenin hiçbir yolu yoktur; 3.4 veya daha düşük bir derleme zamanında SyntaxError alırsınız.

Eğer bir geriye doğru uyumlu bir şekilde yapabileceği yeni özelliklerden yararlanır tek şey yield from kullanarak, (__aiter__, __aenter__, __aexit__, vs.) uygun Sınıflarınızdan çeşitli __a*__ yöntemleri eklemek olduğunu coroutine sözdizimi. Bu şekilde, nesneleriniz async with/async for ifadelerini destekleyebilir, böylece Python 3.5 çalıştıran kitaplığınızın kullanıcıları yeni özelliklerden yararlanabilir. Örneğin

, bu sınıf async with ile kullanılabilir, ancak Python 3.4 yayınlandığında kırmayacak:

Python 3.5 üzerinde
import asyncio 

class Test: 
    def __enter__(self): 
     return self 

    def __exit__(self, *args): 
     print("arg") 

    @asyncio.coroutine 
    def __aenter__(self): 
     yield from self.init_state() 
     return self 

    @asyncio.coroutine 
    def init_state(self): 
     yield from asyncio.sleep(2) # Pretend this is real initialization 

    @asyncio.coroutine 
    def __aexit__(self, *args): 
     return self.__exit__(self, *args) 

:

import asyncio 
from test import Test 

async def main(): 
    print("entering with") 
    async with Test() as t: 
     print("in here") 

loop = asyncio.get_event_loop() 
loop.run_until_complete(main()) 

Python 3.4 üzerinde
import asyncio 
from test import Test 

@asyncio.coroutine 
def oldmain(): 
    print("entering with") 
    with Test() as t: 
     yield from t.init_state() 
     print("in here") 

loop = asyncio.get_event_loop() 
loop.run_until_complete(oldmain()) 

kullanan bir uygulama yazıyorsanız, bu muhtemelen yararlı olmaz., ancak diğer geliştiriciler tarafından kullanılmak üzere tasarlanmış bir kitaplık veya çerçeve geliştiriyorsanız, buna değer.

+6

Sadece en son Python sürümünde göründüğünde "eski" olarak tanımlanan '@ asyncio.coroutine 'yapısını görmek eğlenceli. :-) –

+0

@MarkDickinson Gerçekten de. Python bu alanda oldukça hızlı gelişiyor. :) – dano

+1

Python 2 ve Python 3 arasındaki geçiş çok kolay olduğu için Python topluluğu Python 3.4 ve Python 3.5 arasında geçişi basitleştirmeye karar verdi :-)? – z1naOK9nu8iY5A

İlgili konular