Зефир Python: Ошибка проверки Dict - PullRequest
0 голосов
/ 12 ноября 2018

Я довольно новичок в зефире, но мой вопрос касается проблемы обработки объектов, похожих на диктовку. В документации по «Зефиру» нет работоспособных примеров. Я натолкнулся на простой пример переполнения стека Оригинальный вопрос , и это оригинальный код ответа, предположим, что это должно быть довольно просто

from marshmallow import Schema, fields, post_load, pprint

class UserSchema(Schema):
    name = fields.String()
    email = fields.Email()
    friends = fields.List(fields.String())

class AddressBookSchema(Schema):
    contacts =fields.Dict(keys=fields.String(),values=fields.Nested(UserSchema))

@post_load
def trans_friends(self, item):
    for name in item['contacts']:
        item['contacts'][name]['friends'] = [item['contacts'][n] for n in item['contacts'][name]['friends']]


data = """
   {"contacts": { 
        "Steve": {
            "name": "Steve",
            "email": "steve@example.com",
            "friends": ["Mike"]
        },
        "Mike": {
            "name": "Mike",
            "email": "mike@example.com",
            "friends": []
        }
   }
}
"""

deserialized_data = AddressBookSchema().loads(data)
pprint(deserialized_data)

Однако, когда я запускаю код, я получаю следующее значение NoneType

`None`

Ввод не был назначен.

Я использую последнюю бета-версию зефира 3.0.0b20. Я не могу найти способ сделать эту работу, даже если это выглядит так просто. Похоже, что информация указывает на то, что фреймворк работает с вложенными словарями.

В настоящее время я работаю в приложении каталогизации для фляги, где я получаю сообщения JSON, где я не могу заранее указать схему. Моя конкретная проблема заключается в следующем:

data = """
   {"book": { 
        "title": {
            "english": "Don Quixiote",
            "spanish": "Don Quijote"
            },
        "author": {
            "first_name": "Miguel",
            "last_name": "Cervantes de Saavedra"
            }
        },
    "book": { 
        "title": {
            "english": "20000 Leagues Under The Sea",
            "french": "20000 Lieues Sous Le Mer",
            "japanese": "海の下で20000リーグ",
            "spanish": "20000 Leguas Bajo El Mar",
            "german": "20000 Meilen unter dem Meeresspiegel",
            "russian": "20000 лиг под водой"
            },
        "author": {
            "first_name": "Jules",
            "last_name": "Verne"
            }
        }
    }

Это просто игрушечные данные, но они иллюстрируют, что ключи в словарях не являются фиксированными, они изменяются в количестве и тексте.

Итак, вопросы в том, почему я получаю ошибку проверки в простом, уже сработанном примере, и если возможно использовать инфраструктуру зефира для проверки моих данных,

Спасибо

1 Ответ

0 голосов
/ 16 ноября 2018

В вашем коде есть две проблемы.

Первым является отступ декоратора post_load. Вы ввели это при копировании кода здесь, но у вас его нет в коде, который вы выполняете, иначе вы не получите None.

Второе из-за задокументированного изменения в зефире 3. Ожидается, что функции pre / post_load / dump будут возвращать значение, а не изменять его.

Вот рабочая версия. Я также переделал декоратор:

from marshmallow import Schema, fields, post_load, pprint

class UserSchema(Schema):
    name = fields.String()
    email = fields.Email()
    friends = fields.List(fields.String())

class AddressBookSchema(Schema):
    contacts = fields.Dict(keys=fields.String(),values=fields.Nested(UserSchema))

    @post_load
    def trans_friends(self, item):
        for contact in item['contacts'].values():
            contact['friends'] = [item['contacts'][n] for n in contact['friends']]
        return item


data = """
    {
        "contacts": { 
            "Steve": {
                "name": "Steve",
                "email": "steve@example.com",
                "friends": ["Mike"]
            },
            "Mike": {
                "name": "Mike",
                "email": "mike@example.com",
                "friends": []
            }
        }
    }
"""

deserialized_data = AddressBookSchema().loads(data)
pprint(deserialized_data)

И, наконец, Dict в зефире 2 не имеет функции проверки ключа / значения, поэтому он просто молча проигнорирует аргумент keys и values и не выполнит проверку.

...