关于python:生成器对象上的断言

assertions on a generator object

是否有用于内省生成器对象的技术(例如,用于单元测试中的断言)?

更具体地说,我有一个数据处理管道,它由一系列应用于通常位于列表理解或生成器表达式内部的值的小函数组成,如下所示:

生成一些随机数据:

1
2
3
4
5
6
>>> 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的项应用另一个转换函数,依此类推。

在上面的例子中,断言(例如,关于价格的长度)或其值的最小/最大值等,是我的单元测试套件的核心:

1
>>> assert len(d1) == 10

考虑到我只需要迭代这些中间结果,实际上我不需要列表,生成器对象会这样做,并且考虑到内存配置文件要低得多,这就是我使用的:

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

当然,我在使用列表理解时所依赖的断言对生成器对象不可用:

1
2
3
4
5
6
7
8
>>> 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通常根本不运行它)。

我已经研究了生成器对象的任何属性,以便进行有效的内省,但是我不知道如何以我在这里描述的方式经常使用它们。


生成器对象类型检查的参考

1
2
import types
self.assertIsInstance(_result_generator, types.GeneratorType)

正如@thg435所评论的,在不消耗它的情况下,您不知道生成器的长度。

通常我会做以下一项:

如果发电机产生少量元件:

1
assert len(list(d1)) == 10

1
assert sum(1 for x in d1) == 10