2013-10-05 30 views
1

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

更具体而言,我有由施加到值经常内部列表解析或发电机表达式,像这样小的功能的序列的数据处理管线:

产生一些随机数据:

>>> 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() 

如果我有只是一个断言发电机对象调用列表()然后我的测试套件运行速度非常慢(与不幸的实际结果是德布斯通常不会运行它)。

我已经看过发电机对象的属性,我可以有用的反思,但我没有看到我怎么可以经常使用他们在我这里描述的方式。

+0

发生器对象一个实际上它的功能并不能预先知道它们将返回多少结果。除了实际使用发电机之外,没有办法获得发电机的“长度”。 – georg

+0

如果您想检查生成的序列,只需执行'the_sequence = list(the_generator)',然后执行'the_sequence'上的所有断言。这可以避免为每个* single * assert调用'list'(因为你可以在一次运行中声明长度和内容)。 – Bakuriu

回答

1

由于@ thg435评论,没有消耗它,你不知道发生器的长度。

一般我做下列之一:

在情况下,发电机产生少量的元件:

assert len(list(d1)) == 10 

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