简体   繁体   English

如何使python等待对象

[英]how to make python awaitable object

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 . python 3.5.1中,可以使用await / async,但是,要使用它(因为我不支持),你需要有一个等待的对象 An awaitable object is an object that defines __await__() method returning an iterator. 一个等待对象是一个对象,它定义了返回迭代器的__await__()方法。 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. 但我不能谷歌任何有这个的例子,因为大多数例子都有某种asyncio.sleep(x)来模仿等待对象。

My ultimate goal is to make simple websocket serial server, however, I can't pass this first step. 我的最终目标是制作简单的websocket串口服务器,但是,我无法通过这第一步。 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 你正确地说了

An awaitable object is an object that defines __await__() method returning an iterator 一个等待对象是一个对象,它定义了返回迭代器的__await__()方法

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. 我的意思是,asyncio或其他类似的框架如何在单个线程中实现并发。 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. 这在高级别上很简单:只需将所有代码组织为迭代器,然后逐个调用它们直到值耗尽。

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. 所以,例如,如果你有两个迭代器,让我们说第一个产生字母,第二个产生数字,事件循环调用第一个得到'A' ,然后它调用第二个得到1然后再调用第一个并获取'B'等等,直到迭代器完成。 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. If you have inner loops, use async for - this will allow switching task without explicit yielding. 如果你有内部循环,请使用async for - 这将允许切换任务而不显式屈服。
  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. 在遗留代码的情况下,您可以使用像asyncio.sleep(0) ←这样的hacks,这是asyncio允许在这里切换任务。
  3. No blocking operations! 没有阻止操作! This is most important. 这是最重要的。 Consider you do something like socket.recv() . 考虑你做一些像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() . 这就是在标准库中将其称为async io原因:您必须使用其所有I / O函数的实现,如BaseEventLoop.sock_recv()

I'd recommend you to start (if you didn't yet) with the following docs: 我建议您使用以下文档开始(如果您还没有):

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM