如何使python等待对象 [英] how to make python awaitable object

查看:310
本文介绍了如何使python等待对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

python 3.5.1 中,可以使用await/async,但是,要使用它(据我所知),您需要具有 awaitable对象. 等待对象是定义返回迭代器的__await__()方法的对象.更多信息此处. 但是我无法在Google上找到具有此功能的任何示例,因为大多数示例都具有某种asyncio.sleep(x)来模仿可等待的对象.

In python 3.5.1 one can make use of await/async, however, to use it (as I undestand), you need to have awaitable object. An awaitable object is an object that defines __await__() method returning an iterator. More info here. But I can not google out any example of having this, since most examples have some sort of asyncio.sleep(x) to mimic awaitable object.

我的最终目标是制作简单的websocket串行服务器,但是,我无法通过第一步. 这是我的(非工作代码).

My ultimate goal is to make simple websocket serial server, however, I can't pass this first step. This is my (non working code).

import serial
import asyncio

connected = False
port = 'COM9'
#port = '/dev/ttyAMA0'
baud = 57600
timeout=1

class startser(object):

    def __init__(self, port, baud):
        self.port = port
        self.baud = baud       

    def openconn(self):       
        self.ser = serial.Serial(port, baud)

    async def readport(self):
        #gooo= await (self.ser.in_waiting > 0)
        read_byte = async self.ser.read(1).decode('ascii')        
        self.handle_data(read_byte)
        print ("42")  

    def handle_data(self, data):
        print(data)

serr=startser(port,baud)
serr.openconn()

loop = asyncio.get_event_loop()
#loop.run_forever(serr.readport())
loop.run_until_complete(serr.readport())
loop.close()

print ("finitto")

#with serial.Serial('COM9', 115200, timeout=1) as ser:
    #x = ser.read()          # read one byte
    #s = ser.read(10)        # read up to ten bytes (timeout)
    #line = ser.readline()   # read a '\n' terminated line`

推荐答案

我猜仍然没有答案,因为问题还不清楚. 您正确地说了

I guess there is still no answer because the question is not pretty clear. You correctly said that

等待对象是定义__await__()返回迭代器的方法的对象

An awaitable object is an object that defines __await__() method returning an iterator

在此处添加的内容不多.只需从该方法返回一个迭代器即可.

Not much to add here. Just return an iterator from that method.

您唯一需要了解的是它如何工作.我的意思是,异步或其他类似框架如何在单个线程中实现并发.从高层次上讲,这很简单:只需将所有代码组织为迭代器,然后依次调用它们,直到值用尽.

The only thing you need to understand is how does it work. I mean, how asyncio or another similar framework achieves concurrency in a single thread. This is simple on a high level: just get all your code organized as iterators, then call them one-by-one until the values are exhausted.

例如,如果您有两个迭代器,则假设第一个迭代器生成字母,第二个迭代器生成数字,事件循环调用第一个并获取'A',然后调用第二个并获取1它再次调用第一个,并获取'B',依此类推,直到迭代器完成.当然,这些迭代器中的每一个都可以在产生下一个值之前做任何您想做的事情.但是,花费的时间越长-切换任务"之间的暂停时间就越长.您必须使每次迭代都简短:

So, for example, if you have two iterators, let's say first one yields letters and the second one yields numbers, event loop calls first one and gets 'A', then it calls the second one and gets 1 then it calls first one again and gets 'B' and so on and so on, until the iterators are completed. Of course, each of these iterators can do whatever you want before yielding the next value. But, the longer it takes - the longer pause between 'switching tasks' would be. You MUST keep every iteration short:

  1. 如果您有内部循环,请使用async for-这将允许在不显式屈服的情况下切换任务.
  2. 如果您有大量的代码需要执行数十甚至数百毫秒的时间,请考虑将其重写成小段.对于旧版代码,您可以使用asyncio.sleep(0)这类的黑客程序←这是asyncio在此处切换任务的余地.
  3. 没有阻止操作!这是最重要的.考虑您执行类似socket.recv()的操作.所有任务将停止,直到该调用结束.这就是为什么在标准库中将其称为async io的原因:您必须使用它们对所有I/O功能(例如BaseEventLoop.sock_recv())的实现.
  1. If you have inner loops, use async for - this will allow switching task without explicit yielding.
  2. If you have a lot of code which executes for tens or even hundreds of milliseconds, consider rewriting it in smaller pieces. In a case of legacy code, you can use hacks like asyncio.sleep(0) ← this is an allowance for asyncio to switch task here.
  3. No blocking operations! This is most important. Consider you do something like socket.recv(). All tasks will be stopped until this call ends. This is why this is called async io in the standard library: you must use theirs implementation of all I/O functions like BaseEventLoop.sock_recv().

我建议您从以下文档开始(如果您还没有的话):

I'd recommend you to start (if you didn't yet) with the following docs:

  • https://pymotw.com/3/asyncio/
  • https://docs.python.org/3/library/asyncio.html
  • https://www.python.org/dev/peps/pep-0492

这篇关于如何使python等待对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆