утверждения об объекте-генераторе

Существуют ли методы самоанализа объектов-генераторов (например, для утверждений в модульных тестах)?

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

генерировать некоторые случайные данные:

>>> raw_data = ["${}".format(RND.randint(10, 100)) for c in range(10)]

>>> # a function that does some sort of of transform
>>> fnx = lambda q: float(q.replace('$', ''))

>>> d1 = [fnx(itm) for itm in raw_data]

на следующем шаге к элементам d1 будет применена другая функция преобразования и так далее.

в приведенном выше случае утверждения, например, о длине prices_clean или о минимальном/максимальном его значениях и т. д., являются сердцем моего набора модульных тестов:

>>> assert len(d1) == 10

учитывая, что я просто собираюсь перебирать эти промежуточные результаты, мне на самом деле не нужен список, подойдет объект генератора, и, учитывая гораздо более низкий профиль памяти, это то, что я использую:

>>> d1 = (fnx(itm) for itm in raw_data)

конечно, утверждения, на которые я полагаюсь при использовании списков, недоступны для объектов-генераторов:

>>> d1
  <generator object <genexpr> at 0x106da9230>

>>> assert len(d1) == 10
  Traceback (most recent call last):
  File "<pyshell#33>", line 1, in <module>
    assert len(d1) == 10
  TypeError: object of type 'generator' has no len()

если мне нужно вызвать list() для объекта-генератора только для утверждения, то мой набор тестов работает очень медленно (с неблагоприятным практическим результатом, который debs часто не запускает его вообще).

я просмотрел атрибуты объектов-генераторов для любого, что я могу с пользой для себя изучить, но я не видел, как я могу часто использовать их так, как я описал здесь.


person doug    schedule 05.10.2013    source источник
comment
Объекты-генераторы на самом деле являются функциями и заранее не знают, сколько результатов они вернут. Невозможно получить длину генератора, кроме фактического его потребления.   -  person georg    schedule 05.10.2013
comment
Если вы хотите проверить сгенерированную последовательность, просто выполните the_sequence = list(the_generator), а затем выполните все утверждения для the_sequence. Это позволяет избежать вызова list для каждого утверждения single (поскольку вы можете утверждать как длину, так и содержимое за один проход).   -  person Bakuriu    schedule 05.10.2013


Ответы (2)


Справочник по проверке типа объекта-генератора

import types
self.assertIsInstance(_result_generator, types.GeneratorType)
person Abhijeet    schedule 10.07.2017

Как прокомментировал @thg435, не потребляя его, вы не знаете длину генератора.

Обычно я делаю одно из следующего:

В случае, если генератор производит небольшое количество элементов:

assert len(list(d1)) == 10

or

assert sum(1 for x in d1) == 10
person falsetru    schedule 05.10.2013