いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Pythonメモ-30 (pythonの特殊 else ブロック)(for-else, while-else, try-else)

概要

よく忘れるのでメモメモ。

python には、特殊な else ブロックがあって、for, while, try の部分に else ブロックを持つことができます。

どれも、正常に処理が通った場合に else ブロックに入ります

  • for-else
    • ループが break せずに終了した場合
  • while-else
    • ループが break せずに終了した場合
  • try-else
    • 例外が発生しなかった場合

つまり、空ループの場合でも else ブロックは実行されます。

何かを見つけるような処理を書く場合、見つけた時点で break することが多いため

このような時に else を入れておくと、見つからなかった場合の処理が分かりやすく書けます。

try の場合は、例外が発生せずに正常に処理が通ったときに実行したい処理を分かりやすく書けますね。

サンプル

# coding: utf-8

"""
各処理の後に付与できる オプション else節 についてのサンプルです。
"""
from trypython.common.commoncls import SampleBase
from trypython.common.commonfunc import pr


class Sample(SampleBase):
    def exec(self):
        # ------------------------------------------------------------
        # Pythonの for, while, try には else をつけることが出来る
        # どれも、正常に処理が通った場合に else に入るようになっている。
        #
        # for: ループが break されずに終了した場合
        # while: ループが break されずに終了した場合
        # try: 例外が発生しなかった場合
        #
        # つまり、空ループの場合も、else 部分を通る
        #
        # 何かをサーチするような処理の場合、見つけた時点で break することが
        # 多いため、このようなときに else を入れておくと見つからなかった場合の
        # 処理を簡単に書くことが出来る。
        #
        # tryの場合は、例外が発生せずに正常に処理が通ったときを判定できる
        # ------------------------------------------------------------
        for x in []:
            pr('for-loop', x)
        else:
            pr('for-else', 'passed')

        pr('-----------------------------------', '')

        for x in range(5):
            pr('for-loop', x)
        else:
            pr('for-else', 'passed')

        pr('-----------------------------------', '')

        for x in range(5):
            if x == 3:
                break
            pr('for-loop', x)
        else:
            pr('for-else', 'passed')

        pr('-----------------------------------', '')

        count = 5
        while count >= 0:
            pr('while-loop', count)
            count -= 1
        else:
            pr('while-else', 'passed')

        pr('-----------------------------------', '')

        count = 5
        while count >= 0:
            if count == 2:
                break
            pr('while-loop', count)
            count -= 1
        else:
            pr('while-else', 'passed')

        pr('-----------------------------------', '')

        try:
            pr('try', sum((10, 20,)))
        except MyException as e:
            pr('except', e)
        else:
            pr('try-else', 'passed')

        pr('-----------------------------------', '')

        # noinspection PyUnreachableCode
        try:
            pr('try', sum((10, 20,)))
            raise MyException('this is test exception.')
        except MyException as e:
            pr('except', e)
        else:
            pr('try-else', 'passed')


class MyException(Exception):
    def __init__(self, message: str, *args):
        super().__init__(*args)
        self._message = message

    def __str__(self, *args, **kwargs):
        return f'{self._message}'

    def __repr__(self, *args, **kwargs):
        return self.__str__(*args, **kwargs)


def go():
    obj = Sample()
    obj.exec()


if __name__ == '__main__':
    go()

実行すると以下のようになります。

for-else='passed'
-----------------------------------=''
for-loop=0
for-loop=1
for-loop=2
for-loop=3
for-loop=4
for-else='passed'
-----------------------------------=''
for-loop=0
for-loop=1
for-loop=2
-----------------------------------=''
while-loop=5
while-loop=4
while-loop=3
while-loop=2
while-loop=1
while-loop=0
while-else='passed'
-----------------------------------=''
while-loop=5
while-loop=4
while-loop=3
-----------------------------------=''
try=30
try-else='passed'
-----------------------------------=''
try=30
except=this is test exception.

備考

ちなみに、書籍「Effective Python」では、for-elseとwhile-elseは誤解を招くので使わないほうが良いってなっています。(1章 項目12)

try-else の方は積極的に使うべしってなってますね。(1章 項目13)

Effective Python ―Pythonプログラムを改良する59項目

Effective Python ―Pythonプログラムを改良する59項目


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。