在Python上使用Python的@property装饰器 [英] Using Python's @property decorator on dicts
问题描述
我正在尝试在类中的dict上使用Python的 @property
装饰器。这个想法是,我想要一个值(被称为'message')在被访问之后被清除。但是我也想要另外一个值(称为'last_message')来包含最后一个设置的消息,并保留它,直到设置另一个消息。在我看来,这段代码可以工作:
I'm trying to use Python's @property
decorator on a dict in a class. The idea is that I want a certain value (call it 'message') to be cleared after it is accessed. But I also want another value (call it 'last_message') to contain the last set message, and keep it until another message is set. In my mind, this code would work:
>>> class A(object):
... def __init__(self):
... self._b = {"message": "",
... "last_message": ""}
... @property
... def b(self):
... b = self._b
... self._b["message"] = ""
... return b
... @b.setter
... def b(self, value):
... self._b = value
... self._b["last_message"] = value["message"]
...
>>>
然而,似乎没有:
>>> a = A()
>>> a.b["message"] = "hello"
>>> a.b["message"]
''
>>> a.b["last_message"]
''
>>>
我不知道我做错了什么?在我看来,像 @property
不像我期望的那样对dicts有效,但也许我正在做一些其他从根本上错误的事情?
I'm not sure what I have done wrong? It seems to me like @property
doesn't work like I would expect it to on dicts, but maybe I'm doing something else fundamentally wrong?
另外,我知道我可以在类中使用单个值。但是这是在Web应用程序中实现的一个会话,我需要它作为一个dict。我可以做这个工作,或者使整个session对象假装它是一个dict,或者使用单个的变量,并把它整个代码基础的其余部分进行工作。我很愿意让这个工作。
Also, I know that I could just use individual values in the class. But this is implemented as a session in a web application and I need it to be a dict. I could either make this work, or make the whole session object to pretend it's a dict, or use individual variables and hack it into workingness throughout the rest of the code base. I would much rather just get this to work.
推荐答案
class MyDict(dict):
def __setitem__(self,key,value):
if key=='message':
dict.__setitem__(self,'message','')
dict.__setitem__(self,'last_message',value)
else:
dict.__setitem__(self,key,value)
class A(object):
def __init__(self):
self._b = MyDict({"message": "",
"last_message": ""})
@property
def b(self):
return self._b
a=A()
a.b['message']='hello'
print(a.b['message'])
# ''
print(a.b['last_message'])
# hello
我想你已经发现,你的设置者不工作的原因是因为
As I think you've discovered, the reason why your setter wasn't working is because
a.b['message']='hello'
首次访问 a.b
,它调用了 b
属性的getter,而不是其setter。 getter返回dict self._b
。然后 self._b ['message'] ='hello'
导致dict的 __ setitem __
被调用。
first accesses a.b
, which calls the b
property's getter, not its setter. The getter returns the dict self._b
. Then self._b['message']='hello'
causes the dict's __setitem__
is called .
所以要解决这个问题,你需要一个特殊的dict(如 MyDict
)。
So to fix the problem, you need a special dict (like MyDict
).
这篇关于在Python上使用Python的@property装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!