dir() / vars() / getattr()
| 対応: | Python 2(2000) |
|---|
オブジェクトの属性やメソッドを動的に確認・取得・設定するための組み込み関数です。デバッグや動的プログラミングで活用されます。
構文
# オブジェクトの属性名・メソッド名の一覧を返す dir(オブジェクト) # オブジェクトの __dict__ 属性(属性名と値の辞書)を返す vars(オブジェクト) # オブジェクトの指定した属性の値を取得する getattr(オブジェクト, 属性名, デフォルト値) # オブジェクトの指定した属性に値を設定する setattr(オブジェクト, 属性名, 値) # オブジェクトが指定した属性を持つか確認する hasattr(オブジェクト, 属性名) # オブジェクトの指定した属性を削除する delattr(オブジェクト, 属性名)
関数一覧
| 関数 | 概要 |
|---|---|
| dir(obj) | オブジェクトが持つ属性名とメソッド名のリストを返します。引数なしで呼ぶと現在のスコープの名前一覧を返します。 |
| vars(obj) | オブジェクトの __dict__ を返します。インスタンスの属性と値を辞書形式で確認できます。 |
| getattr(obj, name, default) | オブジェクトから属性名を文字列で指定して値を取得します。属性が存在しない場合はデフォルト値を返します。 |
| setattr(obj, name, value) | オブジェクトの属性名を文字列で指定して値を設定します。存在しない属性名を指定すると新たに作成されます。 |
| hasattr(obj, name) | オブジェクトが指定した名前の属性を持つ場合は True を返します。 |
| delattr(obj, name) | オブジェクトから指定した名前の属性を削除します。 |
サンプルコード
dir_vars_getattr.py
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"こんにちは、{self.name}です。"
p = Person("夜神月", 17)
# dir() でオブジェクトが持つ属性・メソッドを確認
attrs = dir(p)
# __init__, __str__ などの特殊メソッドと name, age, greet が含まれる
# ダンダー(__)で始まる特殊メソッドを除外して表示
public_attrs = [a for a in dir(p) if not a.startswith("_")]
print(public_attrs) # ['age', 'greet', 'name']
# vars() でインスタンスの属性を辞書として取得
print(vars(p)) # {'name': '夜神月', 'age': 17}
# getattr() で属性名を文字列で取得
attr_name = "name"
print(getattr(p, attr_name)) # 夜神月
print(getattr(p, "height", "不明")) # 不明(デフォルト値)
# メソッドも getattr() で取得して呼び出せる
greet_method = getattr(p, "greet")
print(greet_method()) # こんにちは、夜神月です。
# setattr() で属性の値を動的に設定
setattr(p, "age", 18)
print(p.age) # 18
# 新しい属性を動的に追加
setattr(p, "org", "東応大学")
print(p.org) # 東応大学
# hasattr() で属性の存在を確認してから取得
if hasattr(p, "email"):
print(p.email)
else:
print("メールアドレスは登録されていません。")
# delattr() で属性を削除
delattr(p, "org")
print(hasattr(p, "org")) # False
実行すると次のように出力されます。
python3 dir_vars_getattr.py
['age', 'greet', 'name']
{'name': '夜神月', 'age': 17}
夜神月
不明
こんにちは、夜神月です。
18
東応大学
メールアドレスは登録されていません。
False
よくあるミス
よくあるミス1: dir()の結果に存在しないメソッドが含まれる場合がある
『dir()』は継承チェーン上のすべての属性・メソッドを返します。表示された名前が必ずしも直接呼び出せるとは限りません。実際に存在するかは『hasattr()』や『getattr()』で確認します。
class Investigator:
def __init__(self, name, org):
self.name = name
self.org = org
light = Investigator('夜神月', '東応大学')
# dir() は多数の特殊メソッドを含む
attrs = [a for a in dir(light) if not a.startswith('_')]
print(attrs) # ['name', 'org'](ユーザー定義のみ)
# hasattr() で存在確認
print(hasattr(light, 'name')) # True
print(hasattr(light, 'level')) # False
よくあるミス2: getattrのデフォルト値を忘れてAttributeError
『getattr(obj, name)』は属性が存在しない場合に『AttributeError』が発生します。デフォルト値を指定するとエラーを回避できます。
class Investigator:
def __init__(self, name):
self.name = name
light = Investigator('夜神月')
# 存在しない属性にアクセスするとAttributeError
try:
power = getattr(light, 'power') # AttributeError
except AttributeError as e:
print(f'属性なし: {e}')
次のように記述します。
# デフォルト値を指定 power = getattr(light, 'power', 0) # 0が返る(エラーなし) print(power) # 0
概要
これらの関数はPythonのリフレクション(reflection)機能を提供します。属性名を文字列で動的に指定できるため、設定ファイルやユーザー入力に基づいてオブジェクトの属性を操作するようなプログラムに活用できます。
『hasattr()』は内部で『getattr()』を実行して例外の有無を確認します。プロパティが副作用を持つ(データベースアクセスや計算処理など)場合、『hasattr()』を呼んだだけで処理が走ることがあります。このような場合は try-except で属性アクセスを囲む方が安全です。
『dir()』の結果には継承した属性・メソッドも含まれます。そのクラス自身が定義した属性だけを確認したい場合は『vars(ClassName)』でクラスの『__dict__』を直接参照してください。型の確認には『type() / isinstance()』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。