2013-10-05 76 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