代码之家  ›  专栏  ›  技术社区  ›  Carson Myers

在dicts上使用@property decorator

  •  8
  • Carson Myers  · 技术社区  · 14 年前

    我想用蟒蛇的 @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"]
    ''
    >>>
    

    我不知道我做错了什么?在我看来 @房产 不是像我在口述中所期望的那样工作,但也许我在做一些根本错误的事情?

    另外,我知道我可以在课堂上使用个人价值观。但这是作为一个会话在Web应用程序中实现的,我需要它是一个dict。我可以使它工作,或者使整个会话对象假装它是dict,或者使用单个变量并将其黑客化为整个代码库的工作状态。我宁愿让这个工作。

    2 回复  |  直到 6 年前
        1
  •  12
  •   Aran-Fey Swapnil    6 年前
    class MyDict(dict):
        def __setitem__(self, key, value):
            if key == 'message':
                super().__setitem__('message', '')
                super().__setitem__('last_message', value) 
            else:
                super().__setitem__(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
    

    我认为你已经发现,你的二传手不工作的原因是

    a.b['message']='hello'
    

    首次访问 a.b ,它调用 b 属性的getter,而不是其setter。getter返回dict self._b . 然后 self._b['message']='hello' 导致口述 __setitem__ 被称为。

    为了解决这个问题,你需要一个特别的口述(比如 MyDict )

        2
  •  2
  •   sberry    14 年前

    我可能不知道你想在这里做什么,但这能解决你的问题吗?

    class A(object):
        def __init__(self):
            self._b = {'message':'',
                       'last_message': ''}
    
        @property
        def b(self):
            b = self._b.copy()
            self._b['message'] = ''
            return b
    
        @b.setter
        def b(self, value):
            self._b['message'] = value
            self._b['last_message'] = value
    
    
    if __name__ == "__main__":
        a = A()
        a.b = "hello"
        print a.b
        print a.b
        print a.b["last_message"]
    

    $ python dictPropTest.py
    {'last_message': 'hello', 'message': 'hello'}
    {'last_message': 'hello', 'message': ''}
    hello