Pythonで開発を行っていると、ライブラリのオブジェクトがどのようなメソッドを持っているか確認したい場合や、動的に生成されたオブジェクトに特定の変数が存在するかどうかを判定したい場合があります。
このような「オブジェクトの内部調査(イントロスペクション)」を行うために、Pythonには便利な組み込み関数 dir() と hasattr() が用意されています。
この記事では、これら2つの関数の機能と、それぞれの活用シーンについて解説します。
1. dir() 関数:すべての属性をリストアップする
dir() 関数は、引数として渡されたオブジェクトが持っている「すべての属性(変数やメソッド)の名前」を文字列のリストとして返します。
主にデバッグ時や、対話モードでオブジェクトの機能を探る際に使用されます。
具体的な使用例
例として、ゲームのプレイヤーを表すクラスを作成し、そのインスタンスがどのような属性を持っているかを確認します。
class GamePlayer:
def __init__(self, name, level):
self.name = name
self.level = level
def attack(self):
print(f"{self.name}の攻撃!")
# インスタンス化
player = GamePlayer("Hero", 50)
# 属性の一覧を取得
attributes = dir(player)
print(attributes)
実行結果(一部抜粋):
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', ..., '__init__', ..., 'attack', 'level', 'name']
出力されたリストには、自分で定義した name, level, attack に加えて、__init__ や __class__ といったPythonが自動的に付与する特殊メソッド(ダブルアンダースコアで囲まれたもの)もすべて含まれています。
これにより、オブジェクトが持つすべての機能やデータを網羅的に把握できます。
2. hasattr() 関数:特定の属性の存在を確認する
hasattr() 関数は、オブジェクトの中に「特定の名前の属性」が存在するかどうかを調べ、True または False で返します。
構文:
hasattr(オブジェクト, "属性名")
プログラムの実行中に、動的に属性の有無を判定して処理を分岐させる場合に非常に有効です。
具体的な使用例
先ほどの player インスタンスに対して、特定の属性が存在するかを確認します。
# 'name' 属性はあるか?
print(f"name属性の有無: {hasattr(player, 'name')}")
# 'mp' (マジックポイント) 属性はあるか?
print(f"mp属性の有無: {hasattr(player, 'mp')}")
# 'attack' メソッドはあるか?
print(f"attackメソッドの有無: {hasattr(player, 'attack')}")
実行結果:
name属性の有無: True
mp属性の有無: False
attackメソッドの有無: True
実用的な分岐処理
hasattr() を使うことで、属性が存在する場合のみアクセスするという安全なコード記述が可能になります。
# mp属性があれば魔法を唱え、なければ物理攻撃をする
if hasattr(player, "mp"):
print("魔法を唱えました!")
else:
print("MPがないため、物理攻撃を行いました。")
player.attack()
実行結果:
MPがないため、物理攻撃を行いました。
Heroの攻撃!
このように、AttributeError(属性が存在しないエラー)を未然に防ぐことができます。
まとめ
dir(obj): オブジェクトが持つすべての属性名をリストで取得します。主にデバッグや探索目的で使用します。hasattr(obj, "name"): 特定の属性が存在するかどうかをブール値で確認します。プログラム内での条件分岐やエラー回避に使用します。
