简体   繁体   English

python中杰克逊的替代品是什么?

[英]What is the alternative of Jackson in python?

I am using Jackson parser for parsing for Java object to JSON .我正在使用Jackson 解析器将 Java 对象解析为JSON I am forcefully adding JSON keys for some java objects, using the following code.我正在使用以下代码为一些 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") })

I am having same set classes in Python also.我在 Python 中也有相同的设置类。 I would like to do the same thing in python.我想在 python 中做同样的事情。 But not sure about what are the alternatives for this Jackson annotation available in python.但不确定 python 中可用的此 Jackson 注释的替代方案是什么。

My requirement is that I have to send a POST request to a REST API.我的要求是我必须向 REST API 发送 POST 请求。 I need to serialize the java object into JSON.我需要将 java 对象序列化为 JSON。 But as my class structure is a little bit different I don't have all the JSON keys mentioned handy in java classes.但由于我的类结构有点不同,我没有在 java 类中方便地提到所有 JSON 键。 To solve the issue what I am doing is that I am adding 'a' key in JSON when it finds 'A' object is passed from java.为了解决这个问题,我正在做的是当它发现“A”对象是从 java 传递时,我在 JSON 中添加“a”键。 It is doing the same thing for 'F' object.它对“F”对象做同样的事情。 So, I have achieved the solution the way I mentioned above.所以,我已经按照上面提到的方式实现了解决方案。 I want to achieve the same thing in Python.我想在 Python 中实现同样的目标。

Is there some JSON parser available what does the same thing as mentioned above, or I have to follow some different approach for that?是否有一些可用的 JSON 解析器与上面提到的相同,或者我必须遵循一些不同的方法?

I would strongly recommend the pydantic library, which also provides the possibility to add validations of the data.我强烈推荐 pydantic 库,它还提供了添加数据验证的可能性。

It is very easy and straightforward to use, also if you only use it for json marshalling/unmarshalling.它使用起来非常简单直接,如果你只将它用于 json 编组/解组。

https://pypi.org/project/pydantic/ 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))

attrs + cattrs is very close for the task. attrs + cattrs非常适合该任务。

copy one cattr example here,在此处复制一个 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')

but it's not as capable as Jackson, i've not yet been able to find a solution to map attribute between serialized json and deserialized python object.但它没有杰克​​逊那么有能力,我还没有找到在序列化 json 和反序列化 python 对象之间映射属性的解决方案。

I have the same problem and could not find anything suitable.我有同样的问题,找不到任何合适的东西。 So I wrote pyson所以我写了pyson

https://tracinsy.ewi.tudelft.nl/pubtrac/Utilities/wiki/pysonhttps://tracinsy.ewi.tudelft.nl/pubtrac/Utilities/wiki/pyson

It's still under development and I will add new features along the way.它仍在开发中,我将在此过程中添加新功能。 It's not ment to be a complete substitute for jackson as jackson is huge.完全替代杰克逊并不重要,因为杰克逊很大。 I just implement what I need, in jackson style where possible.我只是在可能的情况下以杰克逊风格实现我需要的东西。

I think the most similar option you will get in python ecosystem will be jsonpickle我认为您将在 python 生态系统中获得的最相似的选项是jsonpickle

although it's not as complete as complete Jackson.虽然它不像完整的杰克逊那样完整。 python engineers and users chose a different respectable perspective and that is using schema-less approaches to problems so typing oriented serialization libraries like Jackson doesn't have a strong equivalent in Python. python 工程师和用户选择了不同的可敬观点,即使用无模式方法来解决问题,因此像 Jackson 这样的面向类型的序列化库在 Python 中没有强大的等价物。

You can use Jsonic library.您可以使用Jsonic库。

Jsonic is a lightweight utility for serializing/deserializing python objects to/from JSON. Jsonic 是一个轻量级实用程序,用于将 python 对象序列化/反序列化到 JSON。

Jsonic allows serializing/deserializing to/from specific Class instances. Jsonic 允许对特定的 Class 实例进行序列化/反序列化。

It supports many of the functionalities Jackson supports in Java.它支持 Jackson 在 Java 中支持的许多功能。

Example:例子:

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 has some nifty features: Jsonic 有一些漂亮的功能:

  1. You can serialize objects of types that are not extending Serializable.您可以序列化不扩展 Serializable 类型的对象。 2. This can come handy when you need to serialize objects of third party library classes. 2. 当您需要序列化第三方库类的对象时,这可以派上用场。
  2. Support for custom serializers and deserializers支持自定义序列化器和反序列化器
  3. Serializing into JSON string or python dict序列化为 JSON 字符串或 python dict
  4. Transient class attributes瞬态类属性
  5. Supports both serialization of private fields or leave them out of the serialization process.支持私有字段的序列化或将它们排除在序列化过程之外。

Here you can find some more advanced example:在这里您可以找到一些更高级的示例:

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)

Full disclosure: I'm the creator of Jsonic, i recommend you read the Jsonic GitHub repository README to see if it fits your needs.全面披露:我是 Jsonic 的创建者,我建议您阅读Jsonic GitHub 存储库自述文件,看看它是否符合您的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM