51
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Python] with構文で使用できるクラスを実装する

Last updated at Posted at 2018-11-11

with構文とは

with構文とは後処理が必要な機能を使う際に、使用者がその機能を安全に、そして簡単に使用できるための構文になります。

with構文を使わない場合

with構文を使わないの例をみてみましょう。下のコードになります。

sample_with1.py
from stove import Stove

stove = Stove()
stuff = 'うどん'
print('%sを作ります。' % stuff)

try:
    stove.switch_on()
    stove.boil(stuff)
except:
    raise
finally:
    stove.switch_off()

print('%sができました。' % stuff)

Stoveクラスを使ってうどん茹でています。最初にswitch_onメソッドでコンロに火を点けて、そのあとboilメソッドでうどんを茹でています。そしてfinally句でswitch_offメソッドを呼びコンロの火を消火しています。finally句でswitch_offメソッドを呼び出しているのは、例外が発生しても確実にswitch_offメソッドを呼びたいからです。
finally句は吹きこぼれをしたり、空焚きしてしまうような例外が発生しても確実に消火するための安全装置のようなものになります。

with構文を使用する場合

それでは少し危険なStoveクラスですが、with構文を使用して安全に使用してみましょう。
下のコードになります。

sample_with2.py
from stove import Stove

stuff = 'うどん'
print('%sを作ります。' % stuff)

with Stove() as stove:
    stove.boil(stuff)

print('%sができました。' % stuff)

with構文を使用しない場合に比べてとてもシンプルになりましたが、try,finallyを使用したコードと同じく安全です。まさに安全装置ですね。

with構文で使用できるクラス

それでは、with構文で使用できるクラスとはどのようになっているのかを下の例でみてみます。

stove.py
class Stove():

    def __init__(self):
        self.switch = False

    def switch_on(self):
        if not self.switch:
            self.switch = True
            print('コンロ点火しました')

    def switch_off(self):
        if self.switch:
            self.switch = False
            print('コンロ消火しました')

    def boil(self, stuff):
        print('%sを茹でました。' % stuff)

    def __enter__(self):
        self.switch_on()
        return self

    def __exit__(self, exception_type, exception_value, traceback):
        self.switch_off()

今までの例に出てきたswitch_on、switch_off、boilメソッド以外に**__enter____exit__**といったメソッドがみることができます。この二つのメソッドがwith構文で使用できるために必要なメソッドになります。

**__enter__**メソッドはwithブロック内で呼び出されます。そして戻り値には自身のインスタンスを返却する必要があります。Stoveクラスではコンロの点火も同時に行っています。

**__exit__**メソッドはwithブロックを抜けたときに呼び出されます。また、例外が発生した場合にもこのメソッドは呼ばれるため、例外処理もここに記述します。通常例外はraiseされますが、このメソッドでTrueを返却すると例外を握りつぶすことができます。
Stoveクラスではコンロの消火を行っています。

51
41
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?