🔖
PythonのSimpleNamespaceを拡張して辞書的な値の取得も可能にする
Pythonの標準ライブラリにはtype.SimpleNamespace
というものがあります[1]。SimpleNamespace
を利用すれば,辞書オブジェクトの値に属性アクセスすることが可能になります。例えば,以下のような辞書を考えます。
test_dict1 = {
'key': 'value'
}
test_dict
のkeyキーの値にアクセスする場合,test_dict['key']
のようにする必要があります。しかし,以下のようにtest_dict
にSimpleNamespace
を利用すればtest_dict1.key
のような値のアクセスが可能です。
from types import SimpleNamespace
test_namespace1 = SimpleNamespace(**test_dict1)
print(test_namespace1.key) # value
一方で,辞書をSimpleNamespaceに変換してしまうと,変換後のオブジェクトでは辞書的な値のアクセスができなくなります。
from types import SimpleNamespace
test_namespace1 = SimpleNamespace(**test_dict1)
print(test_namespace1['key']) # これは不可能
したがって,例えば数字が先頭にくるようなキーを持つ辞書をSimpleNamespaceに変換すると,そのキーの値にアクセスすることができなくなります。
from types import SimpleNamespace
test_dict2 = {
'key': 'value'
'1key': '1value'
}
test_namespace2 = SimpleNamespace(**test_dict2)
test_namespace2.1key # エラーになる
属性アクセスと辞書的アクセスを両立させるためには,SimpleNamespaceを拡張して,辞書的アクセスを可能にする必要があります。具体的には以下のように実装できます。
class DictLineNamespace(SimpleNamespace):
def __getitem__(self, key):
return getattr(self, key)
def __setitem__(self, key, value):
return setattr(self, key, value)
test_namespace3 = SimpleNamespace(**test_dict2)
# test_namespace3には辞書のようなアクセスが可能
print(test_namespace3['1key']) # 1value
# SimpleNamespaceを継承しているので属性アクセスも可能
print(test_namespace3.key) # value
__getitem__
および__setitem__
は、[]
を使った辞書的アクセスを処理する特殊メソッドです。__getitem__
は値を取得する場合に呼び出され,__setitem__
は値をセットする場合に呼び出されます。これらのメソッドが呼び出されたときに,getattr
を利用してSimpleNamespaceの値に動的にアクセスして処理を行っています。
このようにして,SimpleNamespaceでも辞書的なアクセスが可能になります。
Discussion