奇怪的 jsonpickle.encode 行为

问题描述

我使用 jsonpickle 作为我的小项目的数据库,在编码复杂类时遇到了一些奇怪的行为,基本上来自 Book 实例的 User 被正确编码,但书籍db 列表被编码为奇怪的 {"py/id":4}-s。 有人可以解释一下我哪里出错了,我该如何解决这个问题

import jsonpickle
from random import randint

admin_ids = [302115492]

def gen_id():
    return randint(1,2**64)

class Book():
    def __init__(self,name,author,img,oid):
        self.name = name
        self.author = author
        self.img = img
        self.id = gen_id()
        self.owner_id = oid

class User():
    id = 0
    name = ""
    books = []
    requests = []

    def __init__(self,uid):
        self.id = uid
        self.name = name
        self.books = []

class Database():
    def __init__(self):
        self.u_dir = "users"
        self.b_dir = "books"
        self.users = []
        self.books = []
    
    def add_book(self,book):
        self.books.append(book)
        for user in self.users:
            if(user.id == book.owner_id):
                user.books.append(book)
    
    def add_user(self,user):
        self.users.append(user)

db=Database()
db.add_user(User('John',123))
db.add_book(Book('name','author','img.png',123))
print(jsonpickle.encode(db))

输出

{
   "py/object":"__main__.Database","u_dir":"users","b_dir":"books","users":[
      {
         "py/object":"__main__.User","id":123,"name":"John","books":[
            {
               "py/object":"__main__.Book","name":"name","author":"author","img":"img.png","id":8045585124766781176,"owner_id":123
            }
         ]
      }
   ],"books":[
      {
         "py/id":4
      }
   ]
}

解决方法

所以显然 jsonpickle 使用这个 id 来紧凑地存储已经存储在对象编码内某处的对象。要显式存储所有对象,可以在编码时使用 make_refs 标志。在上面的代码中,它看起来像这样:print(jsonpickle.encode(db),make_refs=False)