gpt4 book ai didi

python - 任何用于序列化属性的 cattrs 解决方案都使用不同的名称?

转载 作者:行者123 更新时间:2023-12-05 01:38:38 24 4
gpt4 key购买 nike

我试图找到类似于 java Jackson ObjectMapper 的解决方案可以将 python 对象序列化/反序列化为 json。并发现

  • cattrs最接近我需要的。但它不能像在 json 中使用 firstName 但在反序列化对象中使用 first_name 那样进行属性映射。

  • attrs-serde可以做属性映射,不能做递归反序列化。

这个问题可以用这个例子来说明,

import attr
import cattr
from attrs_serde import serde

name_path = ["contact", "personal", "Name"]
phone_path = ["contact", "Phone"]


@serde
@attr.s(auto_attribs=True, frozen=True)
class Name:
first: str
last: str


@serde
@attr.s(auto_attribs=True, frozen=True)
class Person:
name: Name = attr.ib(metadata={"to": name_path, "from": name_path})
phone: str = attr.ib(metadata={"to": phone_path, "from": phone_path})


person_json = {"contact": {"personal": {"Name": {"first": "John", "last": "Smith"}}, "Phone": "555-112233"}}

# XXX: to/from only works on serde
p = Person(name=Name(first="John", last="Smith"), phone="555-112233")
print(p.to_dict())
# {'contact': {'personal': {'Name': {'first': 'John', 'last': 'Smith'}}, 'Phone': '555-112233'}}
p1 = Person.from_dict(person_json)
print(f"p1={p1}")
# p1=Person(name={'first': 'John', 'last': 'Smith'}, phone='555-112233')

# XXX: nested only works on cttrs
person = {"Name": {"First": "John", "Last": "Smith"}, "Phone": "555-112233"}
converter = cattr.Converter()
converter.register_structure_hook(
Person, lambda d, _: Person(name=converter.structure(d["Name"], Name), phone=d.get("Phone"))
)
converter.register_structure_hook(Name, lambda d, _: Name(first=d["First"], last=d.get("Last")))

p2 = converter.structure(person, Person)
print(p2)
assert p == p2

print(converter.unstructure(p2))
# {'name': {'first': 'John', 'last': 'Smith'}, 'phone': '555-112233'}
# {"contact": {"personal": {"name": "John"}, "phone": "555-112233"}}

使用 cattr 的任何更优雅的解决方案?

最佳答案

你可以使用驼峰来进行大小写转换

import humps

import cattr

class CAttrConverter:

converter = cattr.Converter()

def __init__(self):
"""
structure hook for load
unstructure hook for dump
"""

def load(self, params, data_cls, camel_to_snake=True):
"""
:param params: params, mostly from front end
:param data_cls:
:param camel_to_snake: need to convert from camel style to snake style
"""
if camel_to_snake:
params = humps.depascalize(params)
return self.converter.structure(params, data_cls)

def dump(self, data, snake_to_camel=False):
"""
:param data:
:param snake_to_camel: dump as camel case
"""
result: dict = self.converter.unstructure(data)
if snake_to_camel:
result = humps.camelize(result)

return result

关于python - 任何用于序列化属性的 cattrs 解决方案都使用不同的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59494486/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com