👌
Python インスタンス生成時の例外スローを回避する
Python インスタンス生成時の例外スローを回避する
通常、Python でクラスのインスタンスを生成する際、__init__
メソッド内で例外がスローされることがあります。しかし、特定の条件下でインスタンス生成を避けたい場合や、例外をスローせずに None
を返したい場合があります。本記事では、これを実現する3つの方法を紹介します。
- クラスメソッドを使う方法
- ファクトリー関数を使う方法
-
__new__
を使う方法
1. クラスメソッドを使う方法
クラスメソッドを使うことで、インスタンス生成時のバリデーションを行い、失敗した場合に None
を返すことができます。
class MyClass:
def __init__(self, value: int):
if value < 0:
raise ValueError("value must be non-negative")
self.value = value
@classmethod
def create(cls, value: int):
if value < 0:
print("Invalid value, returning None")
return None
return cls(value)
# 使用例
instance = MyClass.create(-1) # Invalid value, returning None
print(instance) # None
2. ファクトリー関数を使う方法
クラス外部にファクトリー関数を用意する方法もあります。この方法では、より柔軟にインスタンス生成ロジックをカプセル化できます。
class MyClass:
def __init__(self, value: int):
self.value = value
def create_myclass(value: int) -> MyClass | None:
if value < 0:
print("Invalid value, returning None")
return None
return MyClass(value)
# 使用例
instance = create_myclass(-1) # Invalid value, returning None
print(instance) # None
__new__
を使う方法(データベース接続の例外処理)
3. __new__
メソッドをオーバーライドして、データベース接続時にエラーが発生した場合にインスタンス生成を中止する方法です。このサンプルでは、データベース接続で例外が発生した場合に None
を返します。
import sqlite3
class DatabaseConnection:
def __new__(cls, db_name: str):
try:
# データベース接続の試行
connection = sqlite3.connect(db_name)
except sqlite3.DatabaseError as e:
print(f"Database connection failed: {e}")
return None # 例外発生時にインスタンス生成を中止
else:
# 接続成功時はインスタンスを生成
instance = super().__new__(cls)
instance.connection = connection
return instance
def __init__(self, db_name: str):
pass # 初期化処理は不要
def close(self):
if hasattr(self, 'connection'):
self.connection.close()
# 使用例
db_instance = DatabaseConnection("non_existent_db.db")
print(db_instance) # Database connection failed: unable to open database file / None
Discussion