【问题标题】:Can't use collections.defaultdict() in google-app-engine无法在 google-app-engine 中使用 collections.defaultdict()
【发布时间】:2018-06-13 14:42:30
【问题描述】:

尝试使用 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

有什么办法解决吗?

【问题讨论】:

  • 请注意,ndb 仅在标准 GAE 环境中受支持,该环境仅适用于 python 2.7。不知道这是否与您的问题有关。
  • @DanCornilescu defaultdict 应该包含在 python2.7 中。docs.python.org/2/library/…
  • 能否提供日志中的追溯信息?
  • 要查看云日志,请参阅here。开发服务器还会生成日志,这些日志可能会写入终端(默认)或文件。另请参阅文档here
  • 如果你这样做my_ds.hist = defaultdict(int) 是否有效?这在本地对我有用,但我还没有在云中尝试过。

标签: python-3.x google-app-engine app-engine-ndb google-app-engine-python defaultdict


【解决方案1】:

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

PickleProperty:值是一个 Python 对象(例如一个列表或一个字典或一个 string) 可以使用 Python 的 pickle 协议进行序列化;云 数据存储将 pickle 序列化存储为 blob。未编入索引 默认。可选关键字参数:压缩。

另请参阅来自 Martijn Pieters 的 answer

Pickle 无法处理 lambda; pickle 只处理数据,而不是代码, 和 lambdas 包含代码。函数可以腌制,但就像 仅当可以导入函数时才定义类。一个函数 可以导入在模块级别定义的。 Pickle 只存储一个 字符串在这种情况下,要导入的函数的完整“路径” 并在再次 unpickling 时引用。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    相关资源
    最近更新 更多