объект не JSON сериализуемый - PullRequest
0 голосов
/ 24 декабря 2018

При кодировании на python я получаю сообщение об ошибке: «Объект типа myObject не является сериализуемым JSON»

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

Часть моего сценария заключается в следующем.Ошибка возникает в последней строке первого блока:

import json
import os
from my_object import myObject

for a in A_set:
    if os.path.isfile(filename):
        with open(filename, 'r') as f:
            json_data = json.load(f)
        object_name = myObject.from_json(json_data)
    else:
        object_name = myObject(a)
        object_name.property_A = property_A
        object_name.property_C = []

    object_name.property_C_add_elements(var)
    with open(filename, 'w') as f:
        json.dump(object_name.to_json(), f)

В другом файле python определен класс 'myObject', где также есть метод 'to_json ()', который я вызываюв строке кода, которая приводит к ошибке.

class myObject:
    def __init__(self, name):
        self.name = name
        self.property_A = property_A
        self.property_B = property_B
        self.property_C = []

    def property_C_add_elements(self, var):  
        self.property_C.append(var)

    def to_json(self):
        return {
            'Name': self.name,
            'property A': self.property_A,
            'property B': self.property_B,
            'property C': self.property_C
        }

    @classmethod
    def from_json(cls, jason_data):
        object_name = myObject(jason_data['property A'])
        property_B = myObject(jason_data['property B'])
        c_list = []
        for var in jason_data['property C']:
            c_list.append(myObject(var))

        object_name.property_B = property_B
        object_name.property_C = c_list

        return object_name

Я был бы рад, если бы я мог найти решение этой проблемы.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Вот измененная (и рабочая) версия вашего кода.

custom_object.py :

class CustomObject:

    @classmethod
    def from_json(cls, json_data):
        name = json_data["Name"]
        prop_a = json_data["PropertyA"]
        prop_b = json_data["PropertyB"]
        obj = cls(name, prop_a=prop_a, prop_b=prop_b)
        for var in json_data["PropertyC"]:
            obj.add_c_element(var)
        return obj

    def __init__(self, name, prop_a="", prop_b=""):
        self.name = name
        self.prop_a = prop_a
        self.prop_b = prop_a
        self.prop_c = list()

    def add_c_element(self, var):
        self.prop_c.append(var)

    def to_json(self):
        return {
            "Name": self.name,
            "PropertyA": self.prop_a,
            "PropertyB": self.prop_b,
            "PropertyC": self.prop_c,
        }

code.py :

#!/usr/bin/env python3

import sys
import json
import os
from custom_object import CustomObject


def main():
    filename = "./data.json"
    if os.path.isfile(filename):
        print("Attempting to load object from json file...")
        with open(filename, "r") as f:
            json_data = json.load(f)
            try:
                obj = CustomObject.from_json(json_data)
            except Exception as e:
                print(e)
                return
            print("Object: {:}\n  Class: {:s}\n  Attributes:" .format(obj, obj.__class__.__name__))
            for k, v in getattr(obj, "__dict__", dict()).items():
                print("    {:s}: {:}".format(k, v))

    else:
        print("Creating dummy object and saving to json...")
        obj = CustomObject("Object name", prop_a="object property a", prop_b="object property b")
        obj.add_c_element(1)
        obj.add_c_element("c element 2")
        with open(filename, "w") as f:
            json.dump(obj.to_json(), f)
    print("Done.")


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()

Примечания :

  • Исправлены ошибки (или добавлены отсутствующие данные)
  • Некоторые переименования (класс, объекты, атрибуты) для ясности
  • Предполагается, что prop_a , prop_b являются строками (не очень важно)
  • (основная) проблема была в from_json функция (я не уверен, что вы пытались сделать там: почему так много myObject экземпляров, когда должен был быть только один).В любом случае, что он делает сейчас:
    1. Получает name , prop_a , prop_b атрибутов из json_data (что является dict )
    2. Создает объект из 3 значений из # 1.
    3. Считать объекты для prop_c ,и добавляет их один за другим (если есть) к объекту (вызывая add_c_element )
  • Программа ищет файл (с json содержимое):
    • Если найден, он пытается загрузить из него объект и отображает его
    • Если не найден, он создает фиктивный объект и выгружает его в файл
  • Это один (не очень хороший) способ ведения дел.Он предназначен для минимальных изменений кода, а также для целей обучения.Правильный (масштабируемый, общий) способ - расширить JSONEncoder , JSONDecoder ( [Python 3]: json - кодер и декодер JSON ), но я чувствуючто это было бы слишком продвинуто на этом этапе

Вывод :

(py35x64_test) e:\Work\Dev\StackOverflow\q053914912>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py
Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32

Creating dummy object and saving to json...
Done.

(py35x64_test) e:\Work\Dev\StackOverflow\q053914912>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py
Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32

Attempting to load object from json file...
Object: <custom_object.CustomObject object at 0x00000230B6182C88>
  Class: CustomObject
  Attributes:
    prop_a: object property a
    prop_b: object property a
    name: Object name
    prop_c: [1, 'c element 2']
Done.
0 голосов
/ 24 декабря 2018

из предоставленного вами кода я могу только предположить, какие типы являются именно вашими property_A, property_B, property_C переменными / атрибутами, но

@classmethod
def from_json(cls, jason_data):
    object_name = myObject(jason_data['property A'])
    property_B = myObject(jason_data['property B'])
    c_list = []
    for var in jason_data['property C']:
        c_list.append(myObject(var))

    object_name.property_B = property_B
    object_name.property_C = c_list

    return object_name

Позвольте мне предположить, что ваши свойства - это Classinstances, у которых нет "определения" того, как онидолжен быть сериализован в JSON.Это подтверждается тем, что вы сказали:

«Объект типа myObject не поддерживает сериализацию в формате JSON»

Я думаю, проблема в методе from_json() class, естьВы, вероятно, должны сделать что-л.например:

EDITED :

Предполагая, что метод __init__() вашего класса выглядит следующим образом

def __init__(self, name, property_A, property_B, property_C):
    self.name = name
    self.property_A = property_A
    self.property_B = property_B
    self.property_C = property_C 
    # property_C should be a list, you may want to add validation method 
    # which checks for correct types if it is preocess cirtical

Я предлагаю следующее:

@classmethod
def from_json(cls, jason_data):
    return cls(
               jason_data['name'],
               jason_data['property A'],
               jason_data['property B'],
               jason_data['property C']
               ) 

Кроме того, я предлагаю, если это возможно, изменить формат JSON, предоставленный в вашем методе to_json(), просто заменив пробельные символы из "свойства A" на "property_A" (то же самое для других свойств),Кроме того, вы можете изменить «Имя» на строчные «имя».

Почему?Потому что с этим форматом и моим измененным __init__() методом вы можете преобразовать from_json() в следующее, используя операцию распаковки:

@classmethod
def from_json(cls, jason_data):
    return cls(**json_data) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...