我观察到以下情况:(Odp 是一个模型)
o = Odp.get(odpKey)
o.foo = 0
foo()
assert o.foo == 1 # fails
def foo():
o = Odp.get(odpKey)
o.foo += 1
o.put()
看起来 o 的第一个副本在它的底层数据存储表示更新时没有刷新。那么,刷新它的首选方式是什么?
我在想:
o = Odp.get(odpKey)
o.foo = 0
foo()
o = Odp.get(o.key())
assert o.foo == 1 # win
或者有更好的方法吗?
请您参考如下方法:
t looks like the first copy of o isn't refreshed when it's underlying datastore representation is updated.
正确:函数foo 执行期间内存中有两个完全独立的对象 -- 两者恰好绑定(bind)到等于o 的裸名,在不同的范围内,但这是一个无关紧要的细节(只是进一步混淆了事情;-)。
o = Odp.get(odpKey)
o.foo = 0
foo()
o = Odp.get(o.key())
assert o.foo == 1 # win
只有第一次“获胜”——因为 o.foo = 0 只影响从未放入数据库的副本,然后 o 被反弹到third 副本刚刚从数据库中获取,那么 o.foo 将是 1 first 时间(如果foo 属性默认为 0) 但后续尝试不会,因为它每次都会增加 1。在调用 foo() 之前,您需要一个 o.put() 来使 o.foo = 0 赋值有任何意义或意义。
一个更好的想法是让 foo 函数接受一个可选参数(有问题的对象),并且只有当它没有接收到时才得到一个新的副本那个论点;然后在任何情况下返回它正在处理的对象。 IOW,你会:
o = Odp.get(odpKey)
o.foo = 0
o = foo(o)
assert o.foo == 1 # always OK
def foo(o=None):
if o is None:
o = Odp.get(odpKey)
o.foo += 1
return o
您可以在某处添加 o.put(),但通常最好仅在一组相关更改已全部应用于内存副本时才保存。基本上在单个内存副本上完成所有工作可以节省大量往返数据库的时间,从而大大加快您的应用程序的速度。
