Сериализация списка экземпляров классов в python - PullRequest
2 голосов
/ 08 апреля 2020

В python я пытаюсь сохранить список в файл. Я пробовал pickle, json, et c, но ни один из них не поддерживает классы, находящиеся в этих списках. Я не могу пожертвовать списками или классами, я должен поддерживать оба. Как я могу это сделать?

Моя текущая попытка:

try:
    with open('file.json', 'r') as file:
        allcards = json.load(file)
except:
    allcards = []

def saveData(list):
    with open('file.json', 'w') as file:
        print(list)
        json.dump(list, file, indent=2)

saveData вызывается в другом месте, и я сделал все тестирование, которое могу, и определил, что ошибка возникает из-за попытки сохранить список из-за включения классов. Он выдает ошибку

Объект типа Card не JSON сериализуемый

всякий раз, когда я выполняю метод JSON, а любой другой метод даже не выдает ошибки, но не загружает список, когда я перезагружаю программу.

Редактировать: Что касается метода pickle, вот как это выглядит:

try:
    with open('allcards.dat', 'rb') as file:
        allcards = pickle.load(file)
        print(allcards)
except:
    allcards = []

class Card():
    def __init__(self, owner, name, rarity, img, pack):
        self.owner = str(owner)
        self.name = str(name)
        self.rarity = str(rarity)
        self.img = img
        self.pack = str(pack)

def saveData(list):
    with open('allcards.dat', 'wb') as file:
        pickle.dump(list, file)

Когда я это делаю, все, что происходит, это то, что код работает как обычно, но список не сохраняется. И печать (allcards) тоже не срабатывает, что заставляет меня поверить, что он каким-то образом не обнаруживает файл или вызывает какую-то другую ошибку, приводящую к тому, что он просто переходит к исключению. Кроме того, предполагается, что img всегда будет ссылкой, в случае, если что-то изменится.

У меня нет другого пути, которым я могу помочь, чтобы решить эту проблему, но я могу опубликовать больше кода, если это будет необходимо.

Пожалуйста, помогите, и спасибо заранее.

Ответы [ 3 ]

0 голосов
/ 08 апреля 2020

Не могли бы вы подтвердить, если это работает:

try:
    with open('file.json', 'r') as file:
        allcards = json.load(file)
except:
    allcards = []

def saveData(list):
    with open('file.json', 'w') as file:
        print(list)
        json.dump(list.__dict__, file, indent=2)
0 голосов
/ 08 апреля 2020

// РЕДАКТИРОВАТЬ Ссылка на приведенную ниже статью хороша, но я написал плохой пример. На этот раз я создал новый фрагмент с нуля - извините за то, что раньше он был более сложным, чем должен.

import json

class Card(object):
    @classmethod
    def from_json(cls, data):
        return cls(**data)

    def __init__(self, figure, color):
        self.figure = figure
        self.color = color

    def __repr__(self):
        return f"<Card: [{self.figure} of {self.color}]>"

def save(cards):
    with open('file.json', 'w') as f:
        json.dump(cards, f, indent=4, default=lambda c: c.__dict__)

def load():
    with open('file.json', 'r') as f:
        obj_list = json.load(f)
        return [Card.from_json(obj) for obj in obj_list]


cards = []
cards.append(Card("1", "clubs"))
cards.append(Card("K", "spades"))
save(cards)

cards_from_file = load()
print(cards_from_file)

Источник

0 голосов
/ 08 апреля 2020
Встроенный модуль

1016 * не поддерживает сериализацию класса python, но есть библиотеки, расширяющие модуль pickle и обеспечивающие эту функциональность. Drill и Cloudpickle оба поддерживают сериализацию класса python и имеют тот же интерфейс, что и модуль рассола.

Укроп: https://github.com/uqfoundation/dill

Облачный рассол: https://github.com/cloudpipe/cloudpickle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...