【发布时间】:2011-03-03 16:08:56
【问题描述】:
我有一个从字典继承的类,以便添加一些自定义行为——在这种情况下,它将每个键和值传递给一个函数进行验证。在下面的示例中,“验证”只是打印一条消息。
对字典的分配按预期工作,每当将项目添加到字典时都会打印消息。但是,当我尝试将自定义字典类型用作类的 __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}
有人可以解释为什么它的行为不符合我的预期吗?它可以或不能按照我尝试的方式工作吗?
【问题讨论】:
-
我不认为你应该替换
__dict__,除非你真的必须替换__new__。您在此处尝试执行的操作应使用自定义__setattribute__方法完成。 -
说实话,我并不是真的“试图做某事”。我正在编写验证 dict 类,只是为了好玩想尝试将其作为
__dict__实例。我提出问题的原因是我真的很想了解它为什么会这样,以及是否有可能绕过它(以及如何绕过它)。
标签: python attributes metaprogramming magic-methods