在try块中没有参数的Python yield

时间:2012-12-28 19:39:28

标签: python

我正在阅读this文章,它显示了这段有趣的代码:

class Car(object):
   def _factory_error_handler(self):
      try:
         yield
      except FactoryColorError, err:
         stacktrace = sys.exc_info()[2]
         raise ValidationError(err.message), None, stacktrace

   def _create_customizer_error_handler(self, vin):
      try:
         yield
      except CustomizerError, err:
         self._factory.remove_car(vin)
         stacktrace = sys.exc_info()[2]
         raise ValidationError(err.message), None, stacktrace

   def _update_customizer_error_handler(self, vin):
      try:
         yield
      except CustomizerError, err:
         stacktrace = sys.exc_info()[2]
         raise ValidationError(err.message), None, stacktrace

   def create(self, color, stereo):
      with self._factory_error_handler():
         vin = self._factory.make_car(color)

      with self._create_customizer_error_handler(vin):
         self._customizer.update_car(vin, stereo)

      return vin

   def update(self, vin, color, stereo):
      with self._factory_error_handler():
         self._factory.update_car_color(vin, color)

      with self._update_customizer_error_handler(vin):
         self._customizer.update_car(vin, stereo)

      return

在这里,他们在try区块中没有参数而屈服。然后在with块内使用它。有人可以解释一下这里发生了什么吗?

1 个答案:

答案 0 :(得分:7)

帖子中的代码似乎有误。如果各种错误处理程序都使用contextmanager进行修饰,那将是有意义的。请注意,在帖子中,代码导入contextmanager但不使用它。这让我觉得这个人在创建帖子时犯了一个错误,并从该示例中离开了contextmanager。 (后面的示例使用contextmanager。)我认为发布的代码会导致AttributeError,因为各种_error_handler函数不是上下文管理器,没有正确的__enter____exit__方法。

使用contextmanager,代码基于the documentation

有意义
  

在生成器产生的点处,执行嵌套在with语句中的块。然后在退出块之后恢复发生器。如果块中发生未处理的异常,则会在生成器发生收益的位置对其进行重新加载。