2012-04-12 11 views
3

私はシリアル接続(pyserial)からラインを読み込んでいますが、私はwhileループを使ってラインを読み込み、その入力に対して一連の関数を実行してからオブジェクト(レンジファインダ)。入力をジェネレータとして扱う方法

私はシリアル入力をジェネレータとして扱うべきだと言われています。

誰もこの経験がありますか?
これは基本的にはどのように達成されるのか説明できますか?
なぜそれが良いですか?純粋に記憶/スピードですか?

EDIT:

at_end() 

から来る:関数がない

? 私が取得しています:

AttributeError: 'Serial' object has no attribute 'at_end'

私は

while True: 
    yield source.readline() 

を使用している場合、私は出力を得ます。

答えて

2

を実装する必要はありませんIterator Typesをご覧ください。基本的には、クラスを実装:

class SerialReader(object): 
    def __init__(self, source): 
     super(SerialReader, self).__init__() 
     self.source = source 

    def next(self): 
     """Provide next piece of data from the serial source.""" 
     # If we have no more data, we have to raise StopIteration exception 
     if self.source.at_end(): 
      raise StopIteration 
     else: 
      return self.source.read() 

    def __iter__(self): 
     return self 

reader = SerialReader(some_serial_source) 

for data in reader: 
    do_something_with_data(data) 

利点は、そのようなイテレータ/発電機を使用することである - あなたはイテレータを受け入れる任意のpython方法でそれを使用することができます。

  • リスト内包表記:sample = [data for data in serial_reader]
  • itertools
  • qickとリストへの簡単な変換:list(serial_reader) - すべてのデータが読み込まれ、リストが返されます
  • ...はるかに多く

非常にpythonicパターンであり、あなたは非常に頻繁に会うことができます。多くのPythonライブラリはイテレータを利用しています。

メモリの使用について:データのストリームを受け入れる別の関数でソースを処理したいとします。すべてのソースデータをロードする必要はありません。ジェネレータ(イテレータ)を処理関数に渡すだけで、必要に応じてデータが読み込まれます。

+1

ジェネレータ関数は、このクラスとまったく同じことを 'def serial_reader(source):source.at_end():yield source.read()'です。少ないクラスで書く! –

+0

@SvenMarnach、at_end()関数はどこから来たのですか?私は私のシリアル接続でそれを呼び出すことはできません。 – beoliver

+0

Pythonのように見えるかもしれませんが、私はシリアルデータのためにこれをしたいという本当のシナリオを想像することはできません。シリアルデータは通常、ストリームから徐々にゆっくり入ってきます。それは頻繁に反復したいデータの塊のようなものではありません。シリアル回線でパケット化されたデータ形式を使用している可能性がありますが、シリアルで直接読み取りを行う場合は、その断片化を保存できません。ちょうどそれのために空想的ではない。あなたのバイトをループで読むことはおそらく大丈夫です。 – TJD

0

Pythonドキュメントは、最高の一つであるので、私はちょうどGenerator documentation

はい、それはメモリとスピードのために純粋であるにリダイレクトます。あなたは何をすべき

+0

PySerialの '' Serial''オブジェクトはイテレータそのものなので、 '' forSerialInstance:... ''で '' for x''を実行することができます。 –

+0

xreadlinesがジェネレータであると思われる関数であることに気付きました – beoliver

1

は次のようになります。これはmyObjectというの値に反復します

for x in myObject: 
    # do stuff with x 

。これが機能するためには、オブジェクトはイテレータプロトコルを実装する必要があります(http://docs.python.org/library/stdtypes.html#iterator-typesを参照)。これは

素晴らしい事は、あなたがインデックスを必要としないということです...リスト、タプル、発電機、dictの上で動作する、そしてオブジェクトはあなたが持っているかもしれません__getitem__

関連する問題