Python学習【365日チャレンジ!】266日目のマスターU(@Udemy11)です。
iPhone12が発売されてすでに10日以上たちましたが、全くもって情報が入ってきません。
というか、情報を収集しようとしていないので、情報がはいってこないのは当たり前ですよね。
iPhone10くらいまでは、きちんと理解できないにもかかわらず、AppleのiPhone発表イベントをリアルタイムで視聴していた時がありましたが、年のせいか
「問題なく使えてるからまーいいや」
状態になってしまっている感はいなめません。
Facebook疲れならぬiPhone疲れになってしまったのでしょうか?
なんてことをいいつつ、今日もPython学習を始めましょう。
昨日の復習
昨日は、デコレーターの引数をスマートに活用できるcontextlib.contextmanagerを学習しました。
contextmanager
を使うことで、デコレーターの引数を使う際にコードを短縮することができました。
また、デコレーターではなく、with
ステートメントを使ってさらに短いコードにすることができたり、with
ステートメントをネストさせて使うこともできました。
くわしくは昨日の記事をごらんください。
今日は、contextlib.ContextDecoratorを学習します。
ContestDecorator
ContextDecorator
のつづりをみてピンと来た方もいるかも知れませんが、キャメルケースなので、クラスです。
ContextDecorator
というクラスを継承したクラスを作成して、いろいろと値をもたせておきたいときに使うことができます。
昨日と同じ出力結果が得られるコードをContextDecorator
を使って書いてみましょう。
import contextlib
class tag(contextlib.ContextDecorator):
def __init__(self, name):
self.name = name
self.start_tag = '<:{}>'.format(name)
self.end_tag = '</{}>'.format(name)
def __enter__(self):
print(self.start_tag)
def __exit__(self, exc_type, exc_val, exc_tb):
print(self.end_tag)
with tag('p'):
print('text')
# @contextlib.contextmanager
# def tag(name):
# print('<:{}>'.format(name))
# yield
# print('</{}>'.format(name))
#
# with tag('p'):
# print('text')
18行目から25行目は参考として、昨日のコードを記述しています。
3行目から13行目で、contextmanager
をデコレーターにした部分をContextDecorator
を継承したtag
クラスに変更しています。
4行目の__init__(self, name)
で引数のname
をself.name
にして、start_tag
とend_tag
に引数のname
を入れて、前後のタグを渡しています。
9行目の__enter__(self)
でstart_tag
を出力して、12行目の__exit__(self, exc_type, exc_val, exc_tb)
でend_tag
を出力しています。
引数のexc_type
、exc_val
、exc_tb
は、エクセプションが起こったときに引数を受け取りますので、デフォルトでNone
が指定されています。
出力結果
<p>
text
</p>
出力結果は昨日と同じになります。
例外を出力してみる
クラスの処理を終了する際の__exit__
には、エクセプションの値を受け取るためのexc_type
、exc_val
、exc_tb
が用意されているので、print出力してエクセプションで何を受け取っているのか確認してみます。
def __exit__(self, exc_type, exc_val, exc_tb):
print(exc_type)
print(exc_val)
print(exc_tb)
print(self.end_tag)
with tag('p'):
raise Exception('Error')
print('text')
出力結果
<p>
<class 'Exception'>
Error
<traceback object at 0x7fe08c09deb0>
</p>
Traceback (most recent call last):
File "/Users/bigmacpro/PycharmProjects/libproject/lesson.py", line 19, in <module>
raise Exception('Error')
Exception: Error
19行目のraise
でエクセプションが起こるので、順番にexc_type
は、class
で、exc_val
は、Error
で、exc_tb
は、traceback object
が出力されています。
最後にraise Exception('Error')
でプログラムが終了しています。
エクセプションを受け取って、なにか処理をさせることができるのもContextDecorator
の特徴ですね。
まとめ
ちょっと複雑過ぎて、理解するのが難しいのですが、今後の実践で便利に使えるということなので、実際に使う場面になってから詳しく理解したほうがいいかもしれません。
デコレーターやwith
ステートメント同様に、ContextDecorator
関数の実行前後になにかの処理をさせることができて、同じ結果を出力することができましたが、コードは全く違いました。
同じアプリを作るにしても、プログラムを書く人によってコードは全く変わってきますが、基本は、きれいで誰が読んでも読みやすいコードを心がけることが大切です。
よりシンプルで見やすいコードを書けるよう、経験を積み上げましょう。
それでは、明日もGood Python!