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