Python - dictproxy

immutable な辞書が必要になったので。

from ctypes import pythonapi, py_object
from _ctypes import PyObj_FromPtr

PyDictProxy_New = pythonapi.PyDictProxy_New
PyDictProxy_New.argtypes = (py_object,)
PyDictProxy_New.rettype = py_object

def make_dictproxy(obj):
    assert isinstance(obj,dict)
    return PyObj_FromPtr(PyDictProxy_New(obj))

from types import DictProxyType as dictproxy

使い方: makedictproxy(辞書オブジェクト)
dictproxy は isinstance でのチェック用。

dictproxy({}) # TypeError, インスタンス生成出来ない。

追記:
書き終わってから、types.DictProxyType がある事に気付く。(コード修正)
元のコードは、dictproxy = type(type('',(),{}).__dict__) だった。

更に後から気付いたけど。
毎回無名のクラスが作られるのさえ気にしなければ、これでも良かった。

make_dictproxy = lambda dictobj: type('',(),dictobj).__dict__


追記2

dictproxy は == immutable dict ではないので、
誤用だからデータ保護等の用途には使わないほうがいいらしい。
ImmutableDict クラス作る方が確実。

 a = dict(val=20)
 b = make_dictproxy(a);
 a['val'] = 10
 print a, b

引数に直接リテラルで記述すると隠せるけど。
問題は、make_dictproxy 側で使い方をチェック出来ない事とか。

 d = make_dictproxy({
  ...
 })