Pythonにおけるオブジェクト指向と例外処理・リフレクションの実践

クラスとインスタンスの関係判定

isinstance(target, ClassType) は、targetが指定クラスのインスタンスかどうかを判定します。

class Vehicle:
    pass

car = Vehicle()
print(isinstance(car, Vehicle))  # True

bike = object()
print(isinstance(bike, Vehicle))  # False

issubclass(SubClass, ParentClass) は、第一引数のクラスが第二引数のサブクラスであるかを確認します。

class Animal:
    pass

class Dog(Animal):
    pass

print(issubclass(Dog, Animal))  # True

例外処理の基本と応用

ユーザーにエラー画面(いわゆる「大黄頁」)を見せないために、例外処理で優しいメッセージを表示できます。

user_input = 'abc'
try:
    num = int(user_input)
except ValueError as err:
    print(f"\033[31m入力エラー: {err}\033[0m")
# 出力: 入力エラー: invalid literal for int() with base 10: 'abc'

代表的な例外タイプ

  • ValueError — 値が不正な場合
  • KeyError — 辞書に存在しないキーを参照した場合
  • IndexError — リストの範囲外アクセス
  • TypeError — 型が不一致の場合
data_list = ['apple', 'banana']
try:
    print(data_list[5])
except IndexError as e:
    print("リストの範囲を超えています:", e)

config = {'host': 'localhost'}
try:
    print(config['port'])
except KeyError as e:
    print("設定キーが見つかりません:", e)

複数例外のキャッチと万能例外

text = "hello"
try:
    result = int(text)
except KeyError:
    print("辞書キーのエラー")
except IndexError:
    print("リストインデックスのエラー")
except Exception as ex:
    print("その他のエラー:", ex)

明示的な例外発生

条件に応じて意図的に例外を発生させることも可能です。

def connect_db():
    return False  # 接続失敗をシミュレート

try:
    if not connect_db():
        raise Exception("\033[31mデータベース接続に失敗しました\033[0m")
except Exception as e:
    print(e)

例外構文の拡張構造

try:
    risky_operation()
except SpecificError:
    handle_specific()
else:
    print("正常終了時の処理")
finally:
    print("必ず実行されるクリーンアップ処理")

カスタム例外の定義

__str__メソッドをオーバーライドすることで、例外メッセージを自由にカスタマイズできます。

class CustomError(Exception):
    def __init__(self, message="不明なエラー"):
        self.message = message

    def __str__(self):
        return self.message

try:
    raise CustomError("独自エラーメッセージです")
except Exception as e:
    print(e)  # 独自エラーメッセージです

アサーションの利用

条件を保証するためにassertを使用します。条件が偽なら例外を発生させます。

assert 2 + 2 == 4, "計算が正しくありません"
# assert 1 == 0, "これは失敗します" → AssertionError

リフレクション(動的属性操作)

文字列を使ってオブジェクトの属性やメソッドを動的に操作できます。

class Machine:
    def __init__(self):
        self.status = "ready"

    def start(self):
        return "起動中..."

device = Machine()

# 属性の存在確認
print(hasattr(device, 'status'))     # True
print(hasattr(device, 'shutdown'))   # False

# 属性取得・設定
action = getattr(device, 'start')
print(action())                      # 起動中...

setattr(device, 'power', 'ON')
print(device.power)                  # ON

delattr(device, 'status')            # 属性削除

モジュールの動的ロード

# 假設有模組 web_handler.py 含有 function: login_page
module_name, func_name = input("モジュール/関数: ").split('/')

mod = __import__(module_name)
target_func = getattr(mod, func_name)
result = target_func()
print(result)

現在のモジュール内でのリフレクション

import sys

def greet():
    print("こんにちは")

current = sys.modules[__name__]
if hasattr(current, 'greet'):
    func = getattr(current, 'greet')
    func()

タグ: Python 例外処理 リフレクション

5月26日 07:10 投稿