【发布时间】:2013-10-12 08:03:58
【问题描述】:
是否有内省生成器对象的技术(例如,用于单元测试中的断言)?
更具体地说,我有一个数据处理管道,其中包含一系列小函数,这些函数通常应用于列表推导或生成器表达式中的值,如下所示:
生成一些随机数据:
>>> 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 通常根本不运行它) .
我已经查看了生成器对象的属性,以了解我可以有效地自省的任何内容,但我没有看到如何以我在此处描述的方式经常使用它们。
【问题讨论】:
-
Generator 对象实际上是函数,事先并不知道它们会返回多少个结果。除了实际使用它之外,没有办法获得生成器的“长度”。
-
如果您想检查生成的序列,只需执行
the_sequence = list(the_generator),然后在the_sequence上执行所有断言。这避免了为每个 single 断言调用list(因为您可以在一次运行中断言长度和内容)。
标签: python unit-testing generator assertion