簡體   English   中英

python中傑克遜的替代品是什么?

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

我正在使用Jackson 解析器將 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 鍵。 為了解決這個問題,我正在做的是當它發現“A”對象是從 java 傳遞時,我在 JSON 中添加“a”鍵。 它對“F”對象做同樣的事情。 所以,我已經按照上面提到的方式實現了解決方案。 我想在 Python 中實現同樣的目標。

是否有一些可用的 JSON 解析器與上面提到的相同,或者我必須遵循一些不同的方法?

我強烈推薦 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))

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')

但它沒有傑克​​遜那么有能力,我還沒有找到在序列化 json 和反序列化 python 對象之間映射屬性的解決方案。

我有同樣的問題,找不到任何合適的東西。 所以我寫了pyson

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

它仍在開發中,我將在此過程中添加新功能。 完全替代傑克遜並不重要,因為傑克遜很大。 我只是在可能的情況下以傑克遜風格實現我需要的東西。

我認為您將在 python 生態系統中獲得的最相似的選項是jsonpickle

雖然它不像完整的傑克遜那樣完整。 python 工程師和用戶選擇了不同的可敬觀點,即使用無模式方法來解決問題,因此像 Jackson 這樣的面向類型的序列化庫在 Python 中沒有強大的等價物。

您可以使用Jsonic庫。

Jsonic 是一個輕量級實用程序,用於將 python 對象序列化/反序列化到 JSON。

Jsonic 允許對特定的 Class 實例進行序列化/反序列化。

它支持 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. 當您需要序列化第三方庫類的對象時,這可以派上用場。
  2. 支持自定義序列化器和反序列化器
  3. 序列化為 JSON 字符串或 python dict
  4. 瞬態類屬性
  5. 支持私有字段的序列化或將它們排除在序列化過程之外。

在這里您可以找到一些更高級的示例:

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 存儲庫自述文件,看看它是否符合您的需求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM