如何使python等待对象

Posted

技术标签:

【中文标题】如何使python等待对象【英文标题】:how to make python awaitable object 【发布时间】:2016-10-09 18:54:39 【问题描述】:

python 3.5.1 中可以使用 await/async,但是,要使用它(我不明白),您需要有 awaitable 对象。 可等待对象是定义了返回迭代器的__await__() 方法的对象。更多信息here。 但我无法通过谷歌搜索出任何具有此功能的示例,因为大多数示例都有某种 asyncio.sleep(x) 来模拟等待对象。

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

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`

【问题讨论】:

serial.Serial() 不是等待对象。最终,您需要创建可等待的 I/O 原语,这些原语知道如何推迟执行直到数据可用。这不适合胆小的人。我认为还没有等待的串口。 @MartijnPieters 我认为串行的原理就像我们处理一些持久的数学算法一样。我不知道的是如何创建等待对象本身(如给出的文档链接中所述)。因为,虽然串行是不可等待的,但它可以“可能”被包装。我承认我不太了解 python,但我会尝试,我希望至少这第一步(创建等待对象)能在这里得到更多解释。 既然还没有建议,你应该看看:docs.python.org/3.5/library/…。我不完全确定您要实现什么,但是从文档中继承 Awaitable 抽象类将允许您创建自定义的“awaitable”对象。 【参考方案1】:

我想仍然没有答案,因为问题不是很清楚。 你说的很对

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

这里没有太多要补充的。只需从该方法返回一个迭代器。

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

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

    如果您有内部循环,请使用 async for - 这将允许切换任务而无需显式让步。 如果您有大量执行数十甚至数百毫秒的代码,请考虑将其重写为更小的部分。在遗留代码的情况下,您可以使用像 asyncio.sleep(0) 这样的 hack ← 这是允许 asyncio 在此处切换任务。 没有阻塞操作!这是最重要的。考虑你做类似socket.recv() 的事情。在此调用结束之前,所有任务都将停止。这就是为什么在标准库中将其称为async io:您必须使用他们对所有 I/O 函数的实现,例如 BaseEventLoop.sock_recv()

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

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

【讨论】:

以上是关于如何使python等待对象的主要内容,如果未能解决你的问题,请参考以下文章

如何使 AsyncTask“doInBackground()”等待一个数组列表

python学习5 爬虫老是被封如何解决

如何使python对象json序列化?

Python - 如何使这个不可腌制的对象可腌制?

如何使类继承自Python中的任何对象

如何使脚本以简单的方式统一等待/休眠