如何处理映射camelCase json到snake_case python数据类字段名?



我使用Python与web api交互,其中json响应中的键在camelCase中。我的python模型是数据类,字段名是snake_case。当我将json转换为model时,反之亦然,名称显然不匹配。

作为参考,我使用asdict函数将我的模型转换为json。

def to_json(self):
return asdict(
self, 
dict_factory=lambda _fields: {
key: value for (key, value) in _fields if value is not None
}
)

将json转换为模型的代码稍微复杂一些,但也依赖于映射到json键的字段名。这两种转换都是通用的,它可以与我所有的模型一起工作,而不必为每个单独的模型(30个左右)创建转换器。

在这种情况下,使用cameCase作为我的模型字段名是常见的做法吗(即使它不符合标准命名实践)?

我不能修改api,不管怎样,键名总是用camelCase。

一种选择是使用datacclass -wizard库,它支持将camelCase(或PascalCasespinal-case)自动映射到snake_case,这是Python中的约定。它最终也应该比marshmallow这样的东西快一点,尽管老实说我还没有自己测试过。

一个简单的例子,取自文档:

from __future__ import annotations
from dataclasses import dataclass, field
from dataclass_wizard import JSONWizard
@dataclass
class MyClass(JSONWizard):
my_str: str | None
is_active_tuple: tuple[bool, ...]
list_of_int: list[int] = field(default_factory=list)
string = """
{
"my_str": 20,
"ListOfInt": ["1", "2", 3],
"isActiveTuple": ["true", false, 1]
}
"""
instance = MyClass.from_json(string)
print(f'{instance!r}')
# MyClass(my_str='20', is_active_tuple=(True, False, True), list_of_int=[1, 2, 3])
print(instance.to_json())
# '{"myStr": "20", "isActiveTuple": [true, false, true], "listOfInt": [1, 2, 3]}'
assert instance == MyClass.from_dict(instance.to_dict())  # True

dataclass-wizard库可以用pip安装:

$ pip install dataclass-wizard

在这种情况下,使用camelCase作为我的模型字段名是常见的做法吗(即使它不符合标准命名实践)?

这不是一种常见的做法,但这是关于惯例的。只要你的代码按照自己的标准是一致的,这应该不是问题。

然而,对于这种情况,有一个简单的解决方案,即在@dataclass_json()注释中使用参数letter_case。我们取@rv。吹毛求疵的人的例子:

@dataclass_json(letter_case=LetterCase.CAMEL)  # now all fields are encoded/decoded from camelCase
@dataclass
class MyClass():
my_str: str | None
is_active_tuple: tuple[bool, ...]
list_of_int: list[int] = field(default_factory=list)

参考:https://pypi.org/project/dataclasses-json/