web-dev-qa-db-ja.com

python待機可能なオブジェクトの作成方法

python 3.5.1では、await/asyncを利用できますが、(私が理解していないように)それを使用するには、awaitable object。待機可能なオブジェクトは、イテレータを返す__await__()メソッドを定義するオブジェクトです。詳細 ここ 。しかし、ほとんどの例には待機可能なオブジェクトを模倣するためのある種の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`
13
nekitip

質問がはっきりしていないので、まだ答えはないと思います。あなたは正しく言った

待機可能なオブジェクトは、イテレータを返す__await__()メソッドを定義するオブジェクトです。

ここに追加することはあまりありません。そのメソッドからイテレータを返すだけです。

あなたが理解する必要がある唯一のことはそれがどのように機能するかです。つまり、asyncioまたは他の同様のフレームワークが単一のスレッドで並行性を実現する方法を意味します。これは大まかに言うと簡単です。すべてのコードをイテレータとして整理し、値がなくなるまで1つずつ呼び出します。

したがって、たとえば、2つのイテレータがある場合、最初のイテレータが文字を生成し、2番目のイテレータが数値を生成すると、イベントループは最初のイテレータを呼び出して_'A'_を取得し、次に2番目のイテレータを呼び出して_1_を取得します。次に、最初の1つを再度呼び出し、イテレータが完了するまで_'B'_などを取得します。もちろん、これらのイテレータはそれぞれ、次の値を生成する前に、必要なことをすべて実行できます。ただし、時間がかかるほど、「タスクの切り替え」間の一時停止が長くなります。あなた[〜#〜] must [〜#〜]すべての反復を短くします:

  1. 内部ループがある場合は、_async for_を使用します。これにより、明示的な譲歩なしでタスクを切り替えることができます。
  2. 数十ミリ秒または数百ミリ秒も実行されるコードがたくさんある場合は、コードを少しずつ書き直すことを検討してください。レガシーコードの場合、asyncio.sleep(0)←のようなハックを使用できます。これは、asyncioがここでタスクを切り替えるための許容値です。
  3. ブロッキング操作はありません!これが最も重要です。 socket.recv()のようなことをするとします。この通話が終了するまで、すべてのタスクが停止します。これが、標準ライブラリで_async io_と呼ばれる理由です。BaseEventLoop.sock_recv()などのすべてのI/O関数の実装を使用する必要があります。

次のドキュメントから始めることをお勧めします(まだ行っていない場合)。

7
Grief