[Python] 例外処理とループ処理を組み合わせた基本的な書き方
Pythonでは、例外処理とループ処理を組み合わせることで、エラーが発生してもプログラムを継続して実行することができます。
例外処理はtry
、except
ブロックを使用して行います。
ループ処理はfor
やwhile
を使用します。
ループ内で例外が発生した場合、except
ブロックでエラーをキャッチし、適切な処理を行うことが可能です。
これにより、特定のエラーが発生した際にループを中断せずに次の反復処理に進むことができます。
- ループ内での基本的な例外処理の方法
- 例外発生時のループの継続や終了の仕組み
- ユーザー入力やファイル操作における例外処理の実践例
- 複数の例外を同時に処理する方法
- 非同期処理における例外処理の活用方法
例外処理とループ処理の組み合わせ
ループ内での例外処理の基本
Pythonでは、try
とexcept
を使用して例外処理を行います。
ループ内で例外処理を組み合わせることで、エラーが発生してもプログラムが停止せず、次のループに進むことができます。
以下は、基本的な例です。
for i in range(5):
try:
print(10 / i) # 0で割ると例外が発生
except ZeroDivisionError:
print("0で割ることはできません。")
このコードを実行すると、0で割ることはできません。
というメッセージが表示され、プログラムは正常に続行されます。
10.0
0で割ることはできません。
5.0
3.3333333333333335
2.5
例外発生時のループ継続
例外が発生した場合でも、ループを継続する方法を示します。
以下のコードでは、リスト内の数値を使って割り算を行い、例外が発生した場合はそのまま次の数値に進みます。
numbers = [10, 0, 5, 2]
for num in numbers:
try:
print(10 / num)
except ZeroDivisionError:
print("0で割ることはできません。")
10.0
0で割ることはできません。
2.0
5.0
例外発生時のループ終了
特定の条件で例外が発生した場合に、ループを終了させる方法もあります。
以下の例では、ValueError
が発生した場合にループを終了します。
numbers = [10, 'a', 5, 2]
for num in numbers:
try:
print(10 / num)
except (ZeroDivisionError, ValueError) as e:
print(f"エラーが発生しました: {e}")
break # ループを終了
10.0
エラーが発生しました: unsupported operand type(s) for /: 'int' and 'str'
例外処理を用いた入力の検証
ユーザーからの入力を検証する際にも、例外処理が役立ちます。
以下のコードでは、ユーザーに数値を入力させ、無効な入力があった場合は再度入力を促します。
while True:
try:
user_input = int(input("数値を入力してください: "))
print(f"入力された数値は: {user_input}")
break # 正常な入力があった場合はループを終了
except ValueError:
print("無効な入力です。数値を入力してください。")
このコードは、ユーザーが数値を入力するまで繰り返しプロンプトを表示します。
無効な入力があった場合は、エラーメッセージを表示し、再度入力を促します。
実践例
ファイル読み込み時の例外処理とループ
ファイルを読み込む際には、ファイルが存在しない場合や読み込みエラーが発生することがあります。
以下のコードでは、複数のファイルを読み込む際に例外処理を用いてエラーを処理し、次のファイルに進む方法を示します。
file_names = ["file1.txt", "file2.txt", "nonexistent.txt"]
for file_name in file_names:
try:
with open(file_name, 'r', encoding='utf-8') as file:
content = file.read()
print(f"{file_name}の内容:\n{content}")
except FileNotFoundError:
print(f"{file_name}が見つかりません。")
except Exception as e:
print(f"{file_name}の読み込み中にエラーが発生しました: {e}")
このコードは、存在しないファイルがあった場合でも、他のファイルの読み込みを続けます。
file1.txtの内容:
Hello, World!
file2.txtの内容:
Python is great!
nonexistent.txtが見つかりません。
ユーザー入力の検証と再入力要求
ユーザーからの入力を検証し、無効な入力があった場合に再度入力を促す方法を示します。
以下のコードでは、数値の入力を求め、無効な場合は再入力を要求します。
while True:
try:
user_input = int(input("整数を入力してください: "))
print(f"入力された整数は: {user_input}")
break # 正常な入力があった場合はループを終了
except ValueError:
print("無効な入力です。整数を入力してください。")
このコードは、ユーザーが正しい整数を入力するまで繰り返しプロンプトを表示します。
APIリクエストのリトライ処理
APIリクエストを行う際に、接続エラーやタイムアウトが発生することがあります。
以下のコードでは、リクエストが失敗した場合にリトライを行う方法を示します。
import requests
import time
url = "https://api.example.com/data"
max_retries = 3
for attempt in range(max_retries):
try:
response = requests.get(url)
response.raise_for_status() # ステータスコードが200以外の場合は例外を発生
print("データを取得しました:", response.json())
break # 正常に取得できた場合はループを終了
except requests.exceptions.RequestException as e:
print(f"リクエストに失敗しました: {e}")
if attempt < max_retries - 1:
print("再試行します...")
time.sleep(2) # 2秒待機
else:
print("最大リトライ回数に達しました。")
このコードは、APIリクエストが失敗した場合に最大3回までリトライを行います。
データベース操作の例外処理とループ
データベースに対する操作でも、例外処理が重要です。
以下のコードでは、複数のSQLクエリを実行し、エラーが発生した場合でも次のクエリに進む方法を示します。
import sqlite3
# データベースに接続
connection = sqlite3.connect('example.db')
cursor = connection.cursor()
queries = [
"CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)",
"INSERT INTO users (name) VALUES ('Alice')",
"INSERT INTO users (name) VALUES ('Bob')",
"INVALID SQL QUERY", # 無効なクエリ
"INSERT INTO users (name) VALUES ('Charlie')"
]
for query in queries:
try:
cursor.execute(query)
connection.commit()
print(f"クエリ実行成功: {query}")
except sqlite3.Error as e:
print(f"クエリ実行中にエラーが発生しました: {e}")
# 接続を閉じる
connection.close()
このコードは、無効なSQLクエリがあった場合でも、他のクエリの実行を続けます。
応用例
複数の例外を処理するループ
Pythonでは、except
ブロックで複数の例外を同時に処理することができます。
以下のコードでは、リスト内の数値を使って割り算を行い、ZeroDivisionError
とValueError
の両方を処理します。
values = [10, 0, 'a', 5, 2]
for value in values:
try:
result = 10 / value
print(f"10 / {value} = {result}")
except (ZeroDivisionError, ValueError) as e:
print(f"エラーが発生しました: {e}")
このコードは、数値以外の値や0で割る場合にエラーメッセージを表示し、プログラムの実行を続けます。
10 / 10 = 1.0
エラーが発生しました: division by zero
エラーが発生しました: unsupported operand type(s) for /: 'int' and 'str'
10 / 5 = 2.0
10 / 2 = 5.0
ネストされたループと例外処理
ネストされたループ内で例外処理を行うことも可能です。
以下の例では、2次元リストの各要素に対して処理を行い、例外が発生した場合は内側のループをスキップします。
data = [[10, 5], [0, 2], ['a', 3], [4, 0]]
for row in data:
for value in row:
try:
result = 10 / value
print(f"10 / {value} = {result}")
except ZeroDivisionError:
print("0で割ることはできません。")
except ValueError:
print("無効な値が含まれています。")
このコードは、各行の値に対して割り算を行い、エラーが発生した場合はその値をスキップします。
10 / 10 = 1.0
10 / 5 = 2.0
0で割ることはできません。
10 / 2 = 5.0
無効な値が含まれています。
10 / 4 = 2.5
0で割ることはできません。
非同期処理と例外処理の組み合わせ
非同期処理を行う際にも、例外処理が重要です。
以下のコードでは、非同期関数を使用してAPIリクエストを行い、例外が発生した場合に適切に処理します。
asyncio
とaiohttp
を使用しています。
import asyncio
import aiohttp
async def fetch_data(session, url):
try:
async with session.get(url) as response:
response.raise_for_status() # ステータスコードが200以外の場合は例外を発生
return await response.json()
except aiohttp.ClientError as e:
print(f"リクエストに失敗しました: {e}")
async def main():
urls = ["https://api.example.com/data1", "https://api.example.com/data2", "https://invalid.url"]
async with aiohttp.ClientSession() as session:
tasks = [fetch_data(session, url) for url in urls]
results = await asyncio.gather(*tasks, return_exceptions=True)
for result in results:
if isinstance(result, Exception):
print(f"エラーが発生しました: {result}")
else:
print("データを取得しました:", result)
# 非同期処理を実行
asyncio.run(main())
このコードは、複数のURLに対して非同期でリクエストを行い、エラーが発生した場合はそのエラーを表示します。
非同期処理を使用することで、効率的にリクエストを行うことができます。
よくある質問
まとめ
この記事では、Pythonにおける例外処理とループ処理の組み合わせについて詳しく解説しました。
例外処理を適切に使用することで、プログラムの安定性を向上させ、エラーが発生してもスムーズに処理を続けることが可能です。
今後は、実際のプログラムに例外処理を取り入れ、より堅牢なコードを書くことを目指してみてください。