python中Jackson的替代方案是什么?

jhdbpxl9  于 2022-11-08  发布在  Python
关注(0)|答案(5)|浏览(213)

我正在使用Jacksonparser将Java对象解析为JSON。我正在使用以下代码为一些Java对象强制添加JSON键。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({ @JsonSubTypes.Type(value = A.class, name = "a"),
        @JsonSubTypes.Type(value = F.class, name = "f") })

我在Python中也有同样的集合类。我想在Python中做同样的事情。但是不确定在Python中有什么可以替代这个Jackson注解。
我的要求是我必须向REST API发送POST请求。我需要将java对象序列化为JSON。但是由于我的类结构有点不同,我没有java类中提到的所有JSON键。为了解决这个问题,我正在做的是,当JSON发现“A”对象从java传递时,我在JSON中添加“a”键。它对“F”做同样的事情。所以,我已经用上面提到的方法实现了解决方案。我想用Python实现同样的事情。
是否有一些JSON解析器可以做上面提到的同样的事情,或者我必须遵循一些不同的方法?

oxf4rvwz

oxf4rvwz1#

我强烈推荐Pydantic库,它还提供了添加数据验证的可能性。
这是非常容易和直接的使用,如果你只使用它的json编组/解组。
https://pypi.org/project/pydantic/

import json
from datetime import datetime

from pydantic import BaseModel

class MyInnerClass(BaseModel):
    timestamp: datetime
    some_string: str

class MyOuterClass(BaseModel):
    inner_instance: MyInnerClass
    other_string: str

# Class to json

test_class = MyOuterClass(inner_instance=MyInnerClass(timestamp=datetime(2022, 6, 22), some_string="some"),
                          other_string="other")

json_string = test_class.json()

# Json to Class

input_string = '{"inner_instance": {"timestamp": "2022-06-22T00:00:00", "some_string": "some"}, "other_string": "other"}'
loaded_class = MyOuterClass(**json.loads(input_string))
os8fio9y

os8fio9y2#

attrs + cattrs对于该任务来说非常接近。
在此复制一个cattr示例,

>>> import attr, cattr
>>>
>>> @attr.s(slots=True, frozen=True)  # It works with normal classes too.
... class C:
...     a = attr.ib()
...     b = attr.ib()
...
>>> instance = C(1, 'a')
>>> cattr.unstructure(instance)
{'a': 1, 'b': 'a'}
>>> cattr.structure({'a': 1, 'b': 'a'}, C)
C(a=1, b='a')

但它功能不如Jackson,所以我还没有找到在序列化的json和反序列化的python对象之间Map属性的解决方案。

ajsxfq5m

ajsxfq5m3#

我也有同样的问题,找不到合适的东西。所以我写了pyson
https://tracinsy.ewi.tudelft.nl/pubtrac/Utilities/wiki/pyson
它还在开发中,我会在开发过程中添加新的功能。这不是一个完整的Jackson替代品,因为Jackson是巨大的。我只是实现我需要的,在Jackson风格的地方。

gj3fmq9x

gj3fmq9x4#

我认为在python生态系统中最相似的选项是jsonpickle
python的工程师和用户选择了一个不同的值得尊敬的观点,那就是使用无模式的方法来解决问题,因此像Jackson这样的面向类型的序列化库在Python中没有一个强有力的等价物。

chy5wohz

chy5wohz5#

您可以使用Jsonic库。
Jsonic是一个轻量级的实用程序,用于将Python对象序列化为JSON或从JSON反序列化Python对象。
Jsonic允许序列化/反序列化到/从特定类示例。
它支持Jackson在Java中支持的许多功能。
示例:

from jsonic import serialize, deserialize

class User(Serializable):
    def __init__(self, user_id: str, birth_time: datetime):
        super().__init__()
        self.user_id = user_id
        self.birth_time = birth_time

user = User('id1', datetime(2020,10,11))      
obj = serialize(user) # {'user_id': 'id1', 'birth_time': {'datetime': '2020-10-11 00:00:00', '_serialized_type': 'datetime'}, '_serialized_type': 'User'}

# Here the magic happens

new_user : User = deserialize(obj) # new_user is a new instance of user with same attributes

Jsonic有一些漂亮的特性:
1.你可以序列化那些没有扩展Serializable的类型的对象。2.当你需要序列化第三方库类的对象时,这会很方便。
1.支持自定义序列化程序和反序列化程序
1.正在序列化为JSON字符串或python dict
1.临时类属性
1.支援私用字段的序列化,或将私用字段排除在序列化行程序之外。
在这里你可以找到一些更高级的例子:

from jsonic import Serializable, register_jsonic_type, serialize, deserialize

class UserCredentials:
"""
Represents class from some other module, which does not extend Serializable
We can register it using register_serializable_type function
"""

def __init__(self, token: str, exp: datetime):
    self.token = token
    self.expiration_time = exp
    self.calculatedAttr = random.uniform(0, 1)

# Register UserCredentials which represents class from another module that does not implement Serializable

# exp __init__ parameter is mapped to expiration_time instace attribute

register_jsonic_type(UserCredentials, init_parameters_mapping={'exp': 'expiration_time'})

class User(Serializable):
    transient_attributes = ['user_calculated_attr'] # user_calculated_attr won't be serialized and deserialzied
    init_parameters_mapping = {'id': 'user_id'} # id __init__ parameter is mapped to user_id instace attribute

    def __init__(self, user_id: str, birth_time: datetime, user_credentials: UserCredentials, *args):
        super().__init__()
        self.user_id = user_id
        self.birth_time = birth_time
        self.user_credentials = user_credentials
        self.user_calculated_attr = 'user_calculated_attr'

user = User(user_id='user_1', birth_time=datetime(1995, 7, 5, 0),
     user_credentials=UserCredentials(token='token', exp=datetime(2020, 11, 1, 0)))

# Here the magic happens

user_json_obj = serialize(user, string_output=True)
new_user = deserialize(user_json_obj, string_input=True, expected_type=User)

充分披露:我是Jsonic的创建者,我建议您阅读Jsonic GitHub repository自述文件,看看它是否符合您的需要。

相关问题