繁体   English   中英

Python 数据类循环解析与棉花糖

[英]Python dataclasses circular parsing with marshmallow

我正在使用 JSON 数据结构,并试图将其表示为数据类。 数据结构(部分)是循环的,我希望嵌套的数据结构也可以整齐地表示为数据类。

我在让数据类正确解析时遇到了一些麻烦。 请参见下面的简化示例:

from typing import List, Optional, Union


class SchemaTypeName(Enum):
    LONG = "long"
    NULL = "null",
    RECORD = "record"
    STRING = "string"


@dataclass_json
@dataclass
class SchemaType():

    type: Union[
        SchemaTypeName,
        'SchemaType',
        List[
            Union[
                SchemaTypeName,
                'SchemaType'
            ]
        ]
    ]

    fields: Optional[List['SchemaType']] = None
    name: Optional[str] = None

下面是使用一些示例数据调用from_dict后返回的 object 的打印输出。 请注意,嵌套的 object(用箭头表示)未正确解析为数据类。

SchemaType(
    type=[
        'null', 
------> {
            'fields': [
                {'name': 'id', 'type': 'string'}, 
                {'name': 'date', 'type': ['null', 'long']}, 
                {'name': 'name', 'type': ['null', 'string']}
            ],
            'type': 'record'
        }
    ]
)

我是否错误地声明了type字段的类型提示?

我正在使用Python 3.9dataclasses_json==0.5.2marshmallow==3.11.1

我发现问题与dataclasses_json在列表中未正确解码我的元素有关。 在列表中混合类型会导致解码器返回基本stringdict的列表,而不会将它们转换为SchemaTypeSchemaTypeName的实例。

但是, dataclasses_json允许您为任何特定字段配置自定义解码器 function。 这是通过从 dataclasses_json 导入config dataclasses_json并将其作为fieldmetadata关键字参数来完成的。 接下来,包含解码器 function 作为configdecoder关键字参数。

请参阅下面的更新示例。 使用schemaTypeDecoder function,我能够将我的数据转换为正确的类型。

from dataclasses import field
from dataclasses_json import config

class SchemaTypeName(Enum):
    ARRAY = "array"
    LONG = "long"
    NULL = "null"
    OBJECT = "object"
    RECORD = "record"
    STRING = "string"


def schemaTypeDecoder(data: Union[str, dict, List[Union[str, dict]]]):

    def transform(schemaType: Union[str, dict]):
        if isinstance(schemaType, str):
            return SchemaTypeName(schemaType)
        else:
            return SchemaType.from_dict(schemaType)

    if isinstance(data, list):
        return [transform(schemaType) for schemaType in data]
    else:
        return transform(data)


@dataclass_json()
@dataclass
class SchemaType():
    type: Union[
        SchemaTypeName,
        'SchemaType',
        List[
            Union[
                SchemaTypeName,
                'SchemaType'
            ]
        ]
    ] = field(
        metadata=config(
            decoder=schemaTypeDecoder
        )
    )

    fields: Optional[List['SchemaType']] = None
    name: Optional[str] = None

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM