4

私はこの記事を読んでいて、この興味深いコードを示していました。

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ブロック内で使用します。誰かがここで何が起こっているのか説明してもらえますか?

4

1 に答える 1

8

投稿のコードが間違っているようです。さまざまなエラーハンドラーがで装飾されていると意味がありますcontextmanager。投稿では、コードはインポートされますcontextmanagerが、使用されないことに注意してください。これは、その人が投稿の作成を間違えただけで、contextmanagerその例から除外されたと思います。(投稿の後半の例では使用しています。)さまざまな関数はコンテキストマネージャーではなく、権限とメソッドがないため、contextmanager投稿されたコードによってが発生すると思います。AttributeError_error_handler__enter____exit__

を使用すると、ドキュメントcontextmanagerに基づいてコードが意味をなします。

ジェネレータが降伏する時点で、withステートメントにネストされたブロックが実行されます。ブロックが終了すると、ジェネレータが再開されます。ブロックで未処理の例外が発生した場合、yieldが発生したポイントでジェネレーター内で再発生します。

于 2012-12-28T19:54:06.000 に答える