簡體   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