Python и JSON: использование object_hook для подсказки классов для нескольких разных классов - PullRequest
0 голосов
/ 06 июля 2010

Используя модуль json в Python 2.6, я испытываю неожиданное поведение при передаче функции в object_hook. Я пытаюсь превратить объект json в класс, определенный в моем коде. Этот класс требует, чтобы экземпляры другого класса были аргументами. Примерно так:

class OuterClass:
    def __init__(self, arg, *InnerClass_instances):
        self.arg = arg
        self.class2 = InnerClass_instances

class InnerClass:
    def __init__(self, name, value):
        self.name = name
        self.value = value 

Мне кажется, что если создать объект JSON, который содержит всю информацию для экземпляра OuterClass, необходимо будет включить всю информацию для каждого экземпляра InnerClass, который будет передан ему. Итак, я подумал, что мог бы написать две функции для анализа объекта JSON, по одной для каждого класса, и иметь функцию, создающую OuterClass, вызывающую функцию, которая создает экземпляры InnerClass. Примерно так:

def create_InnerClass(dct):
    if '__InnerClass__' in dct:
        name = dct['name']
        value = dct['value']
        return InnerClass(name, value)

def create_OuterClass(dct):
    if '__OuterClass__' in dct:
        arg = dct['arg']
        InnerClass_instances = [create_InnerClass(dct2) \
                                for dct2 in dct['InnerClass_instances']]
        return OuterClass(arg, *InnerClass_intances)

Который, я предполагал, подойдет для

s =            #triple quotes omitted for syntax highlighting reasons
{
"__OuterClass__": true,
"arg": 4,
"InnerClass_instances":
    [
    {"__InnerClass__": true, "name": "Joe", "value": 12},
    {"__InnerClass__": true, "name": "Jimmy", "value":7}
    ]
} 

outerClass = json.loads(s, object_hook = creat_OuterClass)

Однако вызов json.loads, как указано выше, возвращает эту ошибку:

if '__InnerClass__' in dct:
TypeError: argument of type 'NoneType' is not iterable

Однако простой вызов json.loads (s), а затем json.dumps (outerClass) работает отлично. Таким образом, кажется, что при таком подходе к параметру object_hook словари, определяющие экземпляры InnerClass, превращаются в объекты NoneType. Мне не хватает понимания того, как функция object_hook используется при разборе объектов JSON?

Есть ли способ сделать подсказку класса для нескольких типов классов в одном объекте JSON? Ничто из того, что я читал до сих пор, не предполагает, что это возможно или невозможно.

1 Ответ

1 голос
/ 06 июля 2010

Не каждый раз, когда вызывается create_OuterClass, будет __OuterClass__ ключом dct.Следовательно, ваш create_OuterClass должен также обработать этот случай.По умолчанию возвращается dct:

def create_OuterClass(dct):
    # print('create_OuterClass: {0}'.format(dct))     
    if '__OuterClass__' in dct:
        arg = dct['arg']
        InnerClass_instances = [create_InnerClass(dct2) \
                                for dct2 in dct['InnerClass_instances']]
        return OuterClass(arg, *InnerClass_instances)
    return dct

Если вы включите приведенный выше оператор печати, вы получите

create_OuterClass: {u'__InnerClass__': True, u'name': u'Joe', u'value': 12}
create_OuterClass: {u'__InnerClass__': True, u'name': u'Jimmy', u'value': 7}
create_OuterClass: {u'__OuterClass__': True, u'InnerClass_instances': [{u'__InnerClass__': True, u'name': u'Joe', u'value': 12}, {u'__InnerClass__': True, u'name': u'Jimmy', u'value': 7}], u'arg': 4}

Это показывает, как json.loads использует обратный вызов object_hookфункция.Сначала это называется внутренними диктовками, а потом - внешними.

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