2.1.2.6 A while-loop删除修饰器

假如我们有一个函数返回事物列表,这个列表由循环创建。如果我们不知道需要多少对象,那么这么做的标准方式是像这样的:

In [18]:

  1. def find_answers():
  2. answers = []
  3. while True:
  4. ans = look_for_next_answer()
  5. if ans is None:
  6. break
  7. answers.append(ans)
  8. return answers

只要循环体足够紧凑,这是可以的。一旦循环体变得更加负责,就像在真实代码中,这种方法的可读性将很差。我们可以通过使用yield语句来简化,不过,这样的话,用户需要显性的调用列表(find_answers())。

我们可以定义一个修饰器来为我们构建修饰器:

In [19]:

  1. def vectorized(generator_func):
  2. def wrapper(*args, **kwargs):
  3. return list(generator_func(*args, **kwargs))
  4. return functools.update_wrapper(wrapper, generator_func)

接下来我们的函数变成:

In [ ]:

  1. @vectorized
  2. def find_answers():
  3. while True:
  4. ans = look_for_next_answer()
  5. if ans is None:
  6. break
  7. yield ans