Python 如何修改从属性装饰器获取的对象?

Python 如何修改从属性装饰器获取的对象?,python,Python,比如说,这里有一个类a。它有一个私有值\u foo,它是一个json字符串,并使用属性getter和setter访问它 代码如下: import json class A(object): _foo = '{"name":"name"}' @property def foo(self): return json.loads(self._foo) @foo.setter def foo(self, value): sel

比如说,这里有一个类
a
。它有一个私有值
\u foo
,它是一个json字符串,并使用属性getter和setter访问它

代码如下:

import json

class A(object):
    _foo = '{"name":"name"}'

    @property
    def foo(self):
        return json.loads(self._foo)

    @foo.setter
    def foo(self, value):
        self._foo = json.dumps(value)
a = A()
print(a.foo['name'])
通常,我使用
foo
执行以下操作:

import json

class A(object):
    _foo = '{"name":"name"}'

    @property
    def foo(self):
        return json.loads(self._foo)

    @foo.setter
    def foo(self, value):
        self._foo = json.dumps(value)
a = A()
print(a.foo['name'])
但是当我想修改它时,我遇到了麻烦

a = A()
print(a.foo)
# Out: {'name': 'name'}
a.foo['weight'] = 1
print(a.foo)
# Out: {'name': 'name'} # have no change
我需要做的是:

foo = a.foo
foo['weight'] = 1
a.foo = foo
print(a.foo)

现在,我的问题是如何实现这一更直观、更通俗的功能?

我认为正确的方法是,不要将dict保存为字符串,而是保存为实际的dict

import json
class A(object):
   _foo = {"name":"name"}

   @property
   def foo(self):
       return self._foo

   @foo.setter
   def foo(self, value):
        self._foo = value

   def dump_foo(self):
       jsons.dump(self.foo)

   def __del__(self):
       self.dump_foo()
我看不出你每次转储json文件、编辑它、使用它以及完成转储后都要转储它的真正原因

  • 如果您仍然希望打印dict(以人类可读的方式),那么由于dict的str转换,您需要做的就是打印(a.foo)

将dict存储为json字符串的整个概念在我看来很奇怪。为什么每次访问dict时都解析JSON,每次修改dict时都序列化JSON?只需加载JSON一次,然后将其存储为dict。使用您想要的语法,没有简单的方法可以做到这一点
a.foo['weight']=1
不是对
a.foo
的赋值。如果您愿意,您可以使用一种黑客方式来执行此操作:不返回正常的dict(或list),而是将其封装在代理对象中,该代理对象可以记住它属于谁,其行为类似于dict(或list),但会覆盖
\uuuuuuuu setitem\uuuuuuuuu
\uuu delitem\uuuuu
,并将其自身分配给
所有者.foo
。但这几乎肯定是个坏主意。@Aran Fey在实际使用中,我会添加一个对象缓存,如
lru_cache
,但在这里,我会删除它,因为它不会影响我的问题。如果你能解释你为什么要这样做(Aran Fey是对的,你几乎总是只想“在边缘”解码和编码JSON)在这两者之间使用普通对象,而不是反复使用,就像你想使用Unicode
str
而不是在每个操作中编码和解码回UTF-8),也许我们可以向你展示一种Pythonic方法来代替。有更好的方法吗?这里没有好的方法来做你想做的事情,但可能有更好的方法来做你真正需要做的事情。这意味着属性的行为像字符串,而不是dict。将其转换为dict,然后在删除时丢弃结果有什么意义?还有,
jsons.dump(self.\uufoo)
?@abarnert我想现在应该可以了,我猜在某个时候他可能真的想把它转储到一个文件中,所以我添加了它以防万一。你的setter和getter现在没有用了,
dump\ufoo
直到至少有两个错误,创建一个JSON字符串,然后在del时将其扔掉仍然是没有用的。@abarnert在他最初的问题中使用的setter在这个新的实现中没有任何用途,但我不知道他首先使用setter有什么额外的用途(这可能是一种过于简单的方法)。至于销毁时的转储,这是为了防止他真的想将其转储到一个文件中(正如我在前面的评论中所述,尽管在这一点上它不包括文件路径)。