[英]Python dataclasses circular parsing with marshmallow
I'm working with a JSON data structure and am trying to represent it as a dataclass.我正在使用 JSON 数据结构,并试图将其表示为数据类。 The data structure is (partly) circular and I want the nested data structures to be neatly represented as dataclasses as well.数据结构(部分)是循环的,我希望嵌套的数据结构也可以整齐地表示为数据类。
I am having some trouble getting the dataclasses to parse correctly.我在让数据类正确解析时遇到了一些麻烦。 See the simplified example below:请参见下面的简化示例:
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
Below is a printout of the object returned after calling from_dict
with some sample data.下面是使用一些示例数据调用from_dict
后返回的 object 的打印输出。 Notice that the nested object (indicated with the arrow) is not parsed as a dataclass correctly.请注意,嵌套的 object(用箭头表示)未正确解析为数据类。
SchemaType(
type=[
'null',
------> {
'fields': [
{'name': 'id', 'type': 'string'},
{'name': 'date', 'type': ['null', 'long']},
{'name': 'name', 'type': ['null', 'string']}
],
'type': 'record'
}
]
)
Am I declaring the type hint for the type
field incorrectly?我是否错误地声明了type
字段的类型提示?
I'm using Python 3.9
with dataclasses_json==0.5.2
and marshmallow==3.11.1
.我正在使用Python 3.9
和dataclasses_json==0.5.2
和marshmallow==3.11.1
。
I found that the problem was related to dataclasses_json
not decoding my elements correctly when they are in a list.我发现问题与dataclasses_json
在列表中未正确解码我的元素有关。 Having mixed types in a list causes the decoder to return a list of basic string
s and dict
s, without transforming them to instances of SchemaType
and SchemaTypeName
.在列表中混合类型会导致解码器返回基本string
和dict
的列表,而不会将它们转换为SchemaType
和SchemaTypeName
的实例。
However, dataclasses_json
allows you to configure a custom decoder function for any particular field.但是, dataclasses_json
允许您为任何特定字段配置自定义解码器 function。 This is done by importing the config
function from dataclasses_json
and providing it as the metadata
keyword argument for field
.这是通过从 dataclasses_json 导入config
dataclasses_json
并将其作为field
的metadata
关键字参数来完成的。 Next, include the decoder function as the decoder
keyword argument for config
.接下来,包含解码器 function 作为config
的decoder
关键字参数。
Please see the updated example below.请参阅下面的更新示例。 Using the schemaTypeDecoder
function, I am able to transform my data to the correct types.使用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.