Python: __dict__やvars()でオブジェクトのプロパティを取得

オブジェクトにどんなプロパティがあるのかを調べたい時、 __dict__vars()関数を使って調べることができます。

__dict__はアンダーバー2つ「__」で囲まれている特殊属性と呼ばれる属性で、 オブジェクトのプロパティと値の組み合わせをディクショナリ(辞書)として取得できます。
vars()関数は組み込み関数です。__dect__と同じ結果を取得できます。

ただしすべてのオブジェクトで使えるわけではなく、 モジュール、クラス、インスタンスなどで、 __dict__属性を持っているオブジェクトに限ります
例えば、文字列・リスト・辞書などは__dict__属性が無いので 使用できません。一方自分で作成したクラスのインスタンス等は __dict__属性があるので取得できます。

__dict__属性があるかどうかを調べるには hasattr()関数で調べます。

# 文字列
s = "hoge"

print(hasattr(s, "__dict__"))  # False

__dict__を使ってプロパティを取得

クラスとそのインスタンスを作成して、 __dict__でプロパティを表示してみます。
Personクラスにはプロパティとして「name」と「age」があります。

class Person:
	# コンストラクタ
	def __init__(self, name, age):
		self.name = name
		self.age = age
		
	def getName(self):
		return self.name

p = Person("山田", 20)

print(p.__dict__)
実行結果
{'name': '山田', 'age': 20}

このように辞書としてプロパティ名と値が取得できます。
結果を1行ずつ表示したい場合は、ディクショナリ(辞書)のItems()メソッドを使います。 下のコードではタプルとして1行ずつ表示しています。 プロパティの数が多い場合はこの方が見やすいと思います。

for v in p.__dict__.items():
	print(v)
実行結果
('name', '山田')
('age', 20)

__dict__属性が無い場合はエラーが発生する

文字列オブジェクトのように、 __dict__属性が無い場合に使用すると次のようにエラーが発生します。 事前にhasattr()関数で調べてください。

s = "hoge"

print(s.__dict__)
実行結果
    print(s.__dict__)
AttributeError: 'str' object has no attribute '__dict__'

vars()でプロパティを取得

組み込み関数のvars()関数でも__dict__と同じ結果を取得できます。

書式
vars(オブジェクト)

vars 組み込み関数 — Pythonドキュメント

先程と同じようにクラスとそのインスタンスを作成して、 vars()でプロパティを表示します。 「p.__dict__」の部分が「vars(p)」に変わるだけです。

class Person:
	# コンストラクタ
	def __init__(self, name, age):
		self.name = name
		self.age = age
		
	def getName(self):
		return self.name

p = Person("山田", 20)

for v in vars(p).items():
	print(v)
実行結果
('name', '山田')
('age', 20)

__dict__属性が無い場合

vars()関数も__dict__の結果を返すだけなので、 __dict__属性が無い場合はエラーとなります。

s = "hoge"

print(vars(s))
実行結果
    print(vars(s))
TypeError: vars() argument must have __dict__ attribute

この記事ではプロパティを取得する方法を紹介しました。
プロパティだけでなく、メソッドや特殊属性も含めたすべての属性を 知りたい場合は次の記事を参考にしてください。 (関連記事: オブジェクトのプロパティとメソッドの一覧を取得

Python