Избегайте использования jsonpickle, используя указатель py/id для другого объекта

Когда объект сериализован в json с использованием jsonpickle, я заметил, что такие объекты, как datetime, сохраняются один раз, а последующие использования сохраняются как ссылочные значения, такие как {"py/id":1}, Можно ли сохранить реальное значение вместо ссылки? Эта ссылка кажется скрытой и может привести к путанице при непосредственном взаимодействии с базой данных.

Ex. class MyClass: def __init__(self, eee): now = datetime.datetime.utcnow() self.ddd = now self.ddd2 = now self.ddd3 = now

Json это {"py/object": "__main__.MyClass", "py/state": {"ddd": {"py/object": "datetime.datetime", "__reduce__": [{"py/type": "datetime.datetime"}, ["B+IBFhYJCwx9oQ=="]]}, "ddd2": {"py/id": 1}, "ddd3": {"py/id": 1}, "eee": "fwaef"}}

4 ответа

Решение

Вы можете использовать make_refs параметр при вызове jsonpickle.encode:

import datetime
import jsonpickle

class MyClass:
    def __init__(self, eee):
        now = datetime.datetime.utcnow()
        self.ddd = now
        self.ddd2 = now
        self.ddd3 = now

my_object = MyClass('hi')
jsonpickle.encode(my_object, make_refs=False)

Из документации здесь:

make_refs - если установлено значение False, поддержка ссылок jsonpickle отключена. Объекты, которые являются id()- идентичными, не будут сохранены в рамках encode()/decode(), но результирующий поток JSON будет концептуально проще. jsonpickle обнаруживает циклические объекты и прерывает цикл, вызывая repr() вместо повторения, когда make_refs имеет значение False.

Новый способ ведения дел. Выше ответ старый.

jsonpickle.encode(my_object, unpicklable=False)

Следует понимать разницу между и при попытке упростить вывод кодировки jsonpickle:

не позволит jsonpickle создавать ссылки (театрибуты) к идентичным объектам. Ссылки делают вывод более компактным, но менее читаемым, и поэтому можно было бы предпочестьза счет большего файла. Однако полученный файл все еще можно декодировать обратно в объект Python.

буквально означает, что вывод jsonpickle не может быть распакован, т.е. декодирован, до исходного типа. Вывод снова более удобочитаем, но если объект, который вы кодируете, содержит неродные типы данных (т. е. классы, определенные вами), вывод кодирования будет хранить значение свойств этих объектов, но если вы попытаетесь декодировать файл обратно в его представлении на Python объекты будут диктовками, а не экземплярами ваших классов.

Попробуйте использовать неотбираемый атрибут, установленный как False

      import datetime
import jsonpickle

class MyClass:
    def __init__(self, eee):
        now = datetime.datetime.utcnow()
        self.ddd = now
        self.ddd2 = now
        self.ddd3 = now

my_object = MyClass('hi')
jsonpickle.encode(my_object, unpicklable=False)
Другие вопросы по тегам