在我看来这是个错误,但也许有人会对此有合理的解释。
考虑以下代码:
class Test(ndb.Model):
a= ndb.IntegerProperty()
p = ndb.PickleProperty(default={})
现在执行以下操作:
^{pr2}$
到这里,一切都很好。但现在:
>> t2 = Test()
>> t2.p
{'a': 1, 'b': 2}
全新的t2实例已经从t1分配了p值?!!在
除了一个错误,还有什么解释吗?
注意,执行t1的put()操作不会改变行为。在
Tags:
在Python中,默认参数会计算一次,因此您使用的是一个单个}。在
dict
(您的default={}
是每个进程的一个dict,而不是每个实体一个dict!)所有类型为Test
的实体,它们恰好在同一个进程中,并且没有显式地为其设置{如果您这样做}就可以了,它有自己的
t=Test(p={})
,那么{dict
。如果你做了t=Test()
,然后t.p = {}
,你也会没事的。但是如果您不以某种方式设置实体的特定p
,那么它将使用相同的默认值dict
,这恰好是同一进程中所有此类实体所使用的默认值p
,它没有显式设置p
。在当您
put
一个Test
实体时,进入数据存储的是它的p
的一个pickle“快照”,当您get
返回时,它将恢复到该状态,并且现在与default
单个-dict
-的其他可能用途断开连接。但这些都是可疑用法中更多的反常现象。在简言之,可变的默认值在Python中不是一个好主意,人们几乎从来没有正确地使用过它们。对
ndb.PickleProperty
的调用与对其他Python可调用对象的调用一样多!在添加:如果您需要一个
PickleProperty
来专门保存dict,并且发现每次实例化这种实体时显式地添加p={}
太麻烦了,那么子类化PickleProperty
可能会有所帮助。一、 电子邮件:如果
default
没有被指定,或者(B)被指定为不是dict
的东西,你想怎么做当然取决于你。这个简单的例子在case(B)中没有任何特殊之处(因此,例如default=[]
仍然会导致问题),但是在case(a)中使用了一个新的empydict
。在或者,您可以尝试将任何提供的}将生成一个新的空
^{pr2}$default
值转换为新的dict
(因此[]
或{dict
,但其他许多值都会引发异常):或者,当然,还有许多其他变体。在
相关问题 更多 >
编程相关推荐