Python 例外処理における with キーワード

Document 对象参考手册Python3 エラーと例外

Python におけるwithステートメントは例外処理に使用され、try…except…finallyコーディングパラダイムをカプセル化し、使いやすさを向上させます。

withステートメントはコードをより明確で読みやすくし、ファイルストリームなどの共通リソースの管理を簡素化します。

ファイルオブジェクトを処理する際に with キーワードを使用するのは良い習慣です。

以下のいくつかのコード例を見てみましょう:

使用しないwith、また使用しないtry…except…finally

実例

file = open('./test_サンプル.txt', 'w')
file.write('hello world !')
file.close()

上記のコードでは、write の呼び出し中に例外が発生した場合、close メソッドが実行されず、リソースがプログラムに占有されたまま解放されないことになります。

Python with キーワードの詳細については、以下を参照してください:https://www.example.com/python3/python3-with-keyword.html

次に、私たちは使用できますtry…except…finallyコードを改善します:

実例

file = open('./test_サンプル.txt', 'w')
try:
    file.write('hello world')
finally:
    file.close()

上記のコードでは、例外が発生する可能性のあるコードに対して try でキャッチし、例外発生時には except コードブロックを実行します。finally コードブロックはどのような場合でも実行されるため、ファイルは閉じられ、例外が発生してもリソースを占有しません。

使用するwithキーワード:

実例

with open('./test_サンプル.txt', 'w') as file:
    file.write('hello world !')

使用するwithwith キーワードを使用すると、システムは自動的に f.close() メソッドを呼び出します。with の効果は try/finally ステートメントと同じです。

with キーワードを実行した後、ファイルが閉じられているかどうかを確認できます:

実例

>>> with open('./test_サンプル.txt') as f:
...     read_data = f.read()

>>> # ファイルが閉じられているか確認する
>>> f.closed
True

with ステートメントの実装原理はコンテキストマネージャーに基づいています。

コンテキストマネージャーは、実装する__enter__と__exit__メソッドのクラスです。

with ステートメントを使用すると、ネストされたブロックの末尾で __exit__ メソッドが確実に呼び出されます。

この概念は try...finally ブロックの使用に似ています。

実例

with open('./test_サンプル.txt', 'w') as my_file:
    my_file.write('hello world!')

上記のインスタンスはhello world!./test_サンプル.txt ファイルに書き込みます。

ファイルオブジェクトには __enter__ と __exit__ メソッドが定義されています。つまり、ファイルオブジェクトもコンテキストマネージャーを実装しており、まず __enter__ メソッドが呼び出され、次に with ステートメント内のコードが実行され、最後に __exit__ メソッドが呼び出されます。エラーが発生しても __exit__ メソッドが呼び出され、ファイルストリームが閉じられます。

実例

以下の Python コードは簡単な旅行計画管理ツールで、5A.txt ファイルから都市リストを読み取り、以下の機能を提供します:

  1. 都市リストの読み取り:ファイルから数字で始まる都市名を読み取り、旅行計画リストに追加します。

  2. 都市の削除:ユーザーは行きたくない都市の数と番号を入力でき、対応する都市を計画から削除します。

  3. 都市の変更:ユーザーは一部の都市の名前を変更して、旅行計画を更新できます。

  4. ランダム旅行計画の生成:都市の順序をシャッフルし、最初の5つの都市を最終的な旅行のおすすめとして表示します。

5A.txt ファイルの各行には、数字で始まる都市名が含まれています:

1. 北京
2. 上海
3. 广州
4. 深圳
5. 成都
6. 杭州
7. 西安
8. 重庆
9. 南京
10. 苏州

実例

from random import shuffle

try:
    with open('5A.txt', 'r') as fp:
        i = [line for line in fp if line[0].isdigit()]
except FileNotFoundError:
    print("ファイル '5A.txt' が見つかりません。ファイルパスを確認してください。")
    exit()

travelList = []

# 旅行都市を追加
for index, item in enumerate(i):
    temp_1 = item.strip()[2:]  # strip を使用して行末の改行を除去
    temp_1 = f"{index}#{temp_1}"
    travelList.append(temp_1)

print("旅行計画都市:", travelList)

# 旅行都市を削除
city_num = input('行きたくない都市の数を入力:')
try:
    for _ in range(int(city_num)):
        index = int(input('行きたくない都市の番号を入力(最初の都市のインデックスは0)'))
        if 0 <= index < len(travelList):
            travelList.pop(index)
            print("旅行計画都市:", travelList)
        else:
            print("入力された番号が範囲外です。")
except ValueError:
    print("有効な整数を入力してください。")

# 旅行都市を変更
city_num = input('変更する旅行予定の都市の数を入力:')
try:
    for _ in range(int(city_num)):
        index = int(input('変更する旅行予定の都市の番号を入力(最初の都市のインデックスは0)'))
        if 0 <= index < len(travelList):
            city_name = input('変更する旅行予定の都市の名前を入力:')
            travelList[index] = city_name
            print('旅行計画都市:', travelList)
        else:
            print("入力された番号が範囲外です。")
except ValueError:
    print("有効な整数を入力してください。")

shuffle(travelList)
print('あなたのTOPS旅行計画を受け取ってください:', travelList[:5])

上記のコードを実行すると、出力結果は以下のようになります:

旅游计划城市: ['0# 北京', '1# 上海', '2# 广州', '3# 深圳', '4# 成都', '5# 杭州', '6# 西安', '7# 重庆', '8# 南京', '9#. 苏州']
输入不想旅游城市的个数:0
输入修改计划旅游的城市个数:3
输入修改计划旅游的城市序号(第1个城市索引为0)4
输入修改计划旅游的城市名称:7
旅游计划城市: ['0# 北京', '1# 上海', '2# 广州', '3# 深圳', '7', '5# 杭州', '6# 西安', '7# 重庆', '8# 南京', '9#. 苏州']

Document 对象参考手册Python3 エラーと例外

その他の拡張