【问题标题】:Implementing iterable for jsonpickle decoded twice实现可迭代的 jsonpickle 解码两次
【发布时间】:2019-07-26 09:58:51
【问题描述】:

当我使用 jsonpickle 对自定义的可迭代类进行编码和解码时,包含的项目会加倍。

我尝试使用 demjson 和 simplejson 并尝试实现这个https://docs.python.org/2.5/ref/sequence-types.html。 如果我从列表继承它确实有效。但我不想继承。 如果我不实施 iter

也可以

我有这样的课:

import jsonpickle
from typing import *

class Product:
    def __init__(self, name):
        self.name = name

class Products:
    def __init__(self):
        self.__products: List[Product] = list()

    def append(self, product: Product):
        self.__products.append(product)

    def __iter__(self):
        return iter(self.__products)

    def __next__(self):
        return next(self.__products)

    def __len__(self):
        return len(self.__products)

    def __getitem__(self, i):
        return self.__products[i]

    def extend(self, products: Iterable[Product]):
        self.__products.extend(products)

当我使用 jsonpickle 对此类进行编码并再次对其进行解码时,包含的产品会翻倍。此示例中引发了 ValueError

if __name__ == '__main__':
    products = Products()
    products.append(Product('abc'))
    encoded = jsonpickle.encode(products)
    decoded_products = jsonpickle.decode(encoded)
    if len(decoded_products) == 2:
        raise ValueError()

如果我使用encoded = jsonpickle.encode(products, make_refs=False),第二个对象是字符串而不是产品

我是否必须实施任何其他方法才能使其正常工作?

【问题讨论】:

    标签: python iterable jsonpickle


    【解决方案1】:

    我认为 jsonpickle 被对象弄糊涂了,看起来像一个序列。

    解码时,首先将__products的值设置为一个完整的列表,然后对每个元素再次调用append。

    我不完全确定为什么会发生这种情况,但您可以使用 Products 中的以下代码对其进行可视化:

    def __setattr__(self, name, value):
        super().__setattr__(name, value)
        print("set", name, value)
    
    def append(self, product: Product):
        print("append", product)
        self.__products.append(product)
    

    您可以通过像这样实现自定义 pickle 协议来修复它:

    class Products:
        def __getstate__(self):
            return self.__products
    
        def __setstate__(self, state):
            self.__products = state
    

    【讨论】:

      猜你喜欢
      • 2013-11-02
      • 1970-01-01
      • 2013-06-30
      • 2021-09-15
      • 2021-09-20
      • 2016-06-15
      • 2017-09-21
      • 2012-01-01
      • 2021-10-05
      相关资源
      最近更新 更多