为解码两次的 jsonpickle 实现可迭代
Implementing iterable for jsonpickle decoded twice
当我使用 jsonpickle 编码和解码自定义可迭代对象 class 时,包含的项目加倍。
我尝试使用 demjson 和 simplejson 并尝试实现这个 https://docs.python.org/2.5/ref/sequence-types.html。
如果我从列表继承它确实有效。但我不想继承。
如果我不实现 iter
它也有效
我有一个 class 这样的:
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 对此 class 进行编码并再次解码时,包含的产品会翻倍。此示例中引发了 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)
第二个对象是字符串而不是产品
我是否必须实施任何其他方法才能正常工作?
我认为 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
当我使用 jsonpickle 编码和解码自定义可迭代对象 class 时,包含的项目加倍。
我尝试使用 demjson 和 simplejson 并尝试实现这个 https://docs.python.org/2.5/ref/sequence-types.html。 如果我从列表继承它确实有效。但我不想继承。 如果我不实现 iter
它也有效我有一个 class 这样的:
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 对此 class 进行编码并再次解码时,包含的产品会翻倍。此示例中引发了 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)
第二个对象是字符串而不是产品
我是否必须实施任何其他方法才能正常工作?
我认为 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