我使用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(或PascalCase或spinal-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/