当前位置: 首页 > 面试题库 >

在字典上使用@property装饰器

漆雕嘉茂
2023-03-14
问题内容

我试图@property在类中的字典上使用Python的装饰器。我的想法是我希望在访问某个值后将其清除(称为“消息”)。但是我还希望另一个值(称为“
last_message”)包含最后设置的消息,并将其保留直到设置了另一个消息。在我看来,此代码将有效:

>>> 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不像我期望的那样起作用,但是也许我在做其他根本上错误的事情?

另外,我知道我可以在类中使用单个值。但这是作为Web应用程序中的会话实现的,我需要将它作为命令。我要么做这项工作,要么使整个会话对象假装成字典,或者使用单个变量将其遍历整个代码库的其余部分。我宁愿让它开始工作。


问题答案:
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。吸气剂返回字典self._b。然后self._b['message']='hello'导致dict__setitem__称为。

因此,要解决此问题,您需要一个特殊的字典(如MyDict)。



 类似资料:
  • 问题内容: 我想了解内置功能的工作原理。令我感到困惑的是,它还可以用作装饰器,但是仅当用作内置函数时才接受参数,而不能用作装饰器。 这个例子来自文档: 的论点是和文档字符串。 在下面的代码中用作装饰器。它的对象是函数,但是在上面的代码中,参数中没有对象函数的位置。 并且,和装饰器是如何创建的?我很困惑。 问题答案: 该函数返回一个特殊的描述符对象: 正是这种对象有额外的方法: 这些充当装饰过。他们

  • 本文向大家介绍Python @property装饰器原理解析,包括了Python @property装饰器原理解析的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Python @property装饰器原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.通过@property装饰器,可以直接通过方法名来访问方法,不需要在方法名后

  • 问题内容: 我有一个带有两个类方法的类(使用函数),用于获取和设置本质上是静态变量的东西。我试图将函数与这些函数一起使用,但会导致错误。我能够在解释器中使用以下代码重现该错误: 我可以演示类方法,但是它们不能用作属性: 是否可以将property()函数与类方法修饰的函数一起使用? 问题答案: 属性是在类上创建的,但会影响实例。因此,如果要使用属性,请在元类上创建该属性。 但是由于无论如何都使用元

  • 我想为我的测试函数构建一个具有多种用途的装饰器。其中之一是帮助向生成的添加属性。 我知道有一个名为的fixture内置pytest,它正好做到了这一点。我如何在我的装饰器内使用这个固定装置? 我知道我可以将夹具直接传递到每个测试函数中,并在测试中使用它,但我有很多测试,这样做似乎非常多余。 另外,我知道我可以使用创建一个自定义标记并在decorator中调用它,但是我有很多文件,我不能单独管理所有

  • 我正在尝试使用Vue 3和TypeScript创建一个新项目。为此,我想使用vue-Property-装饰器,因为我喜欢装饰器的类语法。 我使用Vue CLI创建了一个新的Vue 3 TypeScript项目。 现在,如果我尝试向Vue组件添加vue-Property-装饰器导入,我会在浏览器控制台中收到错误“Super表达式必须为空或为函数”。我的组件如下所示: 该脚本只是粘贴到我的应用程序中的

  • Python @classmethod 为什么不能调用 @property 装饰的属性 ? AttributeError: 'property' object has no attribute 依然不是没清楚