カスタム動作を追加するために辞書から継承するクラスがあります。この場合、検証のために各キーと値が関数に渡されます。以下の例では、「検証」は単にメッセージを出力します。カスタムdictクラスをPythonクラスの__dict__属性として使用したときの奇妙な動作
ディクテーションに項目が追加されるたびにメッセージを出力して、ディクショナリへの割り当てが期待どおりに機能します。しかし、カスタム辞書タイプをクラスの属性として__dict__
として使用しようとすると、属性割り当てによってカスタム辞書クラスにキー/値が配置されるため、__setitem__
をバイパスしながら値を辞書に挿入することができます私が定義した方法でキーを追加することができます)。
カスタム辞書:
from collections import MutableMapping
class ValidatedDict(dict):
"""A dictionary that passes each value it ends up storing through
a given validator function.
"""
def __init__(self, validator, *args, **kwargs):
self.__validator = validator
self.update(*args, **kwargs)
def __setitem__(self, key, value):
self.__validator(value)
self.__validator(key)
dict.__setitem__(self, key, value)
def copy(self): pass # snipped
def fromkeys(validator, seq, v = None): pass # snipped
setdefault = MutableMapping.setdefault
update = MutableMapping.update
def Validator(i): print "Validating:", i
私は理解していないクラスの利回りの挙動の__dict__
属性としてそれを使用します。
>>> d = ValidatedDict(Validator)
>>> d["key"] = "value"
Validating: value
Validating: key
>>> class Foo(object): pass
...
>>> foo = Foo()
>>> foo.__dict__ = ValidatedDict(Validator)
>>> type(foo.__dict__)
<class '__main__.ValidatedDict'>
>>> foo.bar = 100 # Yields no message!
>>> foo.__dict__['odd'] = 99
Validating: 99
Validating: odd
>>> foo.__dict__
{'odd': 99, 'bar': 100}
誰かが私の予想通りに動作しない理由を説明することはできますか?それは私が試みているように働くことができないかできないのですか?
本当に必要な場合は、 '__new__'以外の' __dict__'を置き換えるべきではないと思います。ここでやろうとしていることは、カスタムの '__setattribute__'メソッドで行うべきです。 –
正直言って、私は実際に何かをしようとしていません。検証用のdictクラスを書いていましたが、楽しみのために '__dict__'インスタンスとして試してみたかったのです。私の質問の理由は、なぜそれがこのように振る舞うのか、それを回避することができるのかどうか(そして、どのように)理解できるのかということです。 – porgarmingduod