无法在 google-app-engine 中使用 collections.defaultdict()

Can't use collections.defaultdict() in google-app-engine

尝试使用 collections.defaultdict() 在 google-app-engine 中创建直方图:

class myDS(ndb.Model):

    values = ndb.PickleProperty()
    hist = ndb.PickleProperty()

class Handler:
    my_ds = myDS()
    my_ds.values = {}   
    my_ds.hist = defaultdict(lambda : 0) 

并得到错误(来自日志)

File "/base/alloc/tmpfs/dynamic_runtimes/python27/277b61042b697c7a_unzipped/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1331, in call
    newvalue = method(self, value)
  File "/base/alloc/tmpfs/dynamic_runtimes/python27/277b61042b697c7a_unzipped/python27_lib/versions/1/google/appengine/ext/ndb/model.py", line 1862, in _to_base_type
    return pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed

有什么办法解决这个问题吗?

PickleProperty 字段需要一个可使用 Python 的 pickle 协议序列化的值(有关详细信息,请参阅 docs):

PickleProperty: Value is a Python object (such as a list or a dict or a string) that is serializable using Python's pickle protocol; Cloud Datastore stores the pickle serialization as a blob. Unindexed by default. Optional keyword argument: compressed.

另见来自 Martijn Pieters 的 answer

Pickle cannot handle lambdas; pickle only ever handles data, not code, and lambdas contain code. Functions can be pickled, but just like class definitions only if the function can be imported. A function defined at the module level can be imported. Pickle just stores a string in that case, the full 'path' of the function to be imported and referenced when unpickling again.

有多个选项可以使用默认值,具体取决于您的用例。