【问题标题】:assertions on a generator object生成器对象上的断言
【发布时间】: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


【解决方案1】:

Reference for Type checking of a Generator object

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

【讨论】:

    【解决方案2】:

    正如@thg435 所说,不消费它,你不知道生成器的长度。

    通常我会执行以下操作之一:

    如果生成器产生少量元素:

    assert len(list(d1)) == 10
    

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

    【讨论】:

      猜你喜欢
      • 2021-07-27
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 2022-12-17
      • 2019-12-14
      • 1970-01-01
      • 2021-05-28
      • 1970-01-01
      相关资源
      最近更新 更多