2012-04-12 2 views
3

Я читаю строки из последовательного соединения (pyserial), на данный момент я использую цикл while для чтения строки, а затем выполняю ряд функций на этом входе, а затем сохраняю их в объект (дальномер).Как обрабатывать ввод как генератор

Было упомянуто, что я должен рассматривать последовательный ввод как генератор, так как это делается в python.

У кого-нибудь есть опыт?
Или может, по крайней мере, объяснить в принципе, как это будет достигнуто?
Почему это лучше? Это чисто для памяти/скорости?

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) 

Advantage является использование такого итератора/генератора - вы можете использовать его с любым методом питона, который принимает итераторы:

  • список понимания: sample = [data for data in serial_reader]
  • itertools
  • qick и простое преобразование в список: list(serial_reader) - прочитает все данные и вернет список
  • ... и многое другое

Итератор очень питоновский, и вы можете встретить довольно часто. Многие библиотеки python используют итераторы.

Что касается использования памяти: представьте, что вы хотите обработать свой источник с помощью другой функции, которая принимает поток данных.Вам не нужно загружать все исходные данные, вы просто передаете генератор (итератор) в функцию обработки, и данные будут считаны по мере необходимости.

+1

Функция генератора, выполняющая то же самое, что и этот класс, - 'def serial_reader (source): while not source.at_end(): yield source.read()'. Напиши меньше уроков! –

+0

@SvenMarnach, откуда берется функция at_end()? Я не могу назвать это своим серийным подключением. – beoliver

+0

Хотя это может показаться pythonic, я не могу представить себе реальный сценарий, где вы захотите сделать это для последовательных данных. Серийные данные обычно поступают медленно и постоянно из потока. Это не часто, как капли данных, которые вы хотите перебирать. У вас может быть пакетный формат данных по последовательному каналу, но вы не можете сохранить эту фрагментацию при прямом чтении в последовательном интерфейсе. Не радуйтесь только ради этого. Чтение ваших байтов в цикле, вероятно, просто отлично. – TJD

0

Python документация один из лучших, так что я буду просто перенаправить вас на Generator documentation

Да, это чисто для памяти и скорости.

+0

Обратите внимание, что объекты PySerial '' Serial'' сами являются итераторами, поэтому вы можете просто выполнить '' для x в someSerialInstance: ... ''. –

+0

Я заметил, что xreadlines была функцией, которая также казалась генератором. – beoliver

1

Что вы должны сделать, это:

for x in myObject: 
    # do stuff with x 

это итерацию по значениям в MyObject. Для этого объект должен реализовать протокол итератора (см. http://docs.python.org/library/stdtypes.html#iterator-types). Это будет работать на список, кортеж, генераторы, ДИКТ ...

Хорошая вещь в том, что вам не нужно индекса, и что объект не должен реализовать __getitem__