python 嵌套字典转json对象_Python中的嵌套对象模型,支持 字典、YAML和JSON转换

Related is a Python library for creating nested object models that can be serialized to and de-serialized from nested python dictionaries. When paired with other libraries (e.g. PyYAML), Related object models can be used to convert to and from nested data formats (e.g. JSON, YAML).

Example use cases for related object models include:

Configuration file reading and writing

REST API message response generation and request processing

Object-Document Mapping for a document store (e.g. MongoDB, elasticsearch)

Data import parsing or export generation

Requirements

Python (2.7, 3.5, 3.6)

Installation

Install using pip...

pip install related

First Example

import related

@related.immutable

class Person(object):

first_name = related.StringField()

last_name = related.StringField()

@related.immutable

class RoleModels(object):

scientists = related.SetField(Person)

people = [Person(first_name="Grace", last_name="Hopper"),

Person(first_name="Katherine", last_name="Johnson"),

Person(first_name="Katherine", last_name="Johnson")]

print(related.to_yaml(RoleModels(scientists=people)))

Yields:

scientists:

- first_name: Grace

last_name: Hopper

- first_name: Katherine

last_name: Johnson

Second Example

The below example is based off of this Docker Compose example. It shows how a YAML file can be loaded into an object model, tested, and then generated back into a string that matches the original YAML.

version: '2'

services:

web:

build: .

ports:

- 5000:5000

volumes:

- .:/code

redis:

image: redis

Below is the related object model that represents the above configuration. Notice how the name-based mapping of services (i.e. web, redis) are represented by the model.

import related

@related.immutable

class Service(object):

name = related.StringField()

image = related.StringField(required=False)

build = related.StringField(required=False)

ports = related.SequenceField(str, required=False)

volumes = related.SequenceField(str, required=False)

command = related.StringField(required=False)

@related.immutable

class Compose(object):

version = related.StringField(required=False, default=None)

services = related.MappingField(Service, "name", required=False)

The above yaml can then be loaded by using one of the convenience method and then round-tripped back to yaml to check that the format has been maintained. The related module uses OrderedDict objects in order to maintain sort order by default.

from os.path import join, dirname

from model import Compose

from related import to_yaml, from_yaml, to_model

YML_FILE = join(dirname(__file__), "docker-compose.yml")

def test_compose_from_yml():

original_yaml = open(YML_FILE).read().strip()

yml_dict = from_yaml(original_yaml)

compose = to_model(Compose, yml_dict)

assert compose.version == '2'

assert compose.services['web'].ports == ["5000:5000"]

assert compose.services['redis'].image == "redis"

generated_yaml = to_yaml(compose,

suppress_empty_values=True,

suppress_map_key_values=True).strip()

assert original_yaml == generated_yaml

More Examples

More examples can be found by reviewing the tests/ folder of this project. Below are links and descriptions of the tests provided so far.

Example

description

First example above that shows how SetFields work.

Second example above that demonstrates YAML (de)serialization.

Compose v3 with long-form ports and singledispatch to_dict

A single class (Company) with a bunch of value fields.

A multi-class object model with Enum class value field.

Handling of renaming of attributes including Python keywords.

Basic JSON (de)serialization with TimeField, DateTimeField and DecimalField.

Function decorator that converts inputs to obj and outputs to dict

Handle self-referencing and out-of-order references using strings.

Documentation

Below is a quick version of documentation until more time can be dedicated.

Overview

The attrs library is the underlying engine for related. As explained in this article by Glyph, attrs cleanly and cleverly eliminates a lot of the boilerplate required when creating Python classes without using inheritance. Some core functionality provided by attrs:

Generated initializer method (__init__)

Generated comparison methods (__eq__, __ne__, __lt__, __le__, __gt__, __ge__ )

Human-readable representation method (__repr__)

Attribute converter and validator framework

The related project is an opinionated layer built on top of the attrs library that provides the following:

Value fields that handle both validation and conversion to and from basic data types like str, float, and bool.

Nested fields that support relationships such as Child, Sequences, Mappings, and Sets of objects.

to_dict function that converts nested object graphs to python dictionaries. Made customizable (without resorting to monkey-patching) by the singledispatch library.

to_model function that instantiated classes used by the de-serialization process going from python dictionaries to the related model.

Conversion helper functions (to_yaml, from_yaml, to_json, from_json) for easily going between related models and data formats.

@mutable and @immutable for decorating classes as related models without the need for inheritance increasing maintainability and flexibility.

Class Decorators

decorator

description

@mutable

Activate a related class that instantiates changeable objects.

@immutable

Activate a related class that instantiates unchangeable objects.

See the decorators.py file to view the source code until proper documentation is generated.

Field Types

field type

description

BooleanField

bool value field.

ChildField

Child object of a specified type cls.

DateField

date field formatted using formatter.

DateTimeField

datetime field formatted using formatter.

TimeField

time field formatted using formatter.

FloatField

float value field.

IntegerField

int value field.

MappingField(cls,key)

Dictionary of objects of type cls index by key field values.

RegexField(regex)

str value field that is validated by re.match(regex).

SequenceField(cls)

List of objects all of specified type cls.

SetField

Set of objects all of a specified type cls.

StringField

str value field.

URLField

UUIDField

UUID object, will create uuid4 by default if not specified.

Adding your own field types is fairly straightforward due to the power of the underlying attrs project. See the fields.py file to see how the above are constructed.

Functions

function

description

from_json(s,cls)

Convert a JSON string or stream into specified class.

from_yaml(s,cls)

Convert a YAML string or stream into specified class.

is_related(obj)

Returns True if object is @mutable or @immutable.

to_dict(obj)

Singledispatch function for converting to a dict.

to_json(obj)

Convert object to a (pretty) JSON string via to_dict.

to_model(cls,value)

Convert a value to a cls instance.

to_yaml(obj)

Convert object to a YAML string via to_dict.

See the functions.py file to view the source code until proper documentation is generated.

Credits/Prior Art

The related project has been heavily influenced by the following projects that might be worth looking at if related doesn't meet your needs.

attrs - The engine that powers related functionality.

Django ORM - Object-relational mapping for Django that inspired related's design.

cattrs - Alternative take for handling nested-objects using attrs.

addict and box - Python dictionary wrappers that do not require a model.

Jackson - Java-based technology for serializing and de-serializing objects.

License

The MIT License (MIT) Copyright (c) 2017 Ian Maurer, Genomoncology LLC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值