简体   繁体   English

python 数据类的自动自定义构造函数

[英]Automatic custom constructor for python dataclass

I'm trying to create a custom constructor for my python dataclass that will ideally take in a dict (from request json data) and fill in the attributes of the dataclass.我正在尝试为我的 python 数据类创建一个自定义构造函数,理想情况下它将接受一个字典(来自请求 json 数据)并填写数据类的属性。

Eg例如

@dataclass
class SoldItem:
    title: str
    purchase_price: float
    shipping_price: float
    order_data: datetime

def main():
    json = requests.get(URL).json()
    sold_item = SoldItem(json)

So I want SoldItem to have a method that saves the json data in the appropriate attributes of the dataclass instead of having to do SoldItem(title=json['title']...所以我希望 SoldItem 有一种方法可以将 json 数据保存在数据类的适当属性中,而不必执行SoldItem(title=json['title']...

I would also preferably have the class be able to recognise that the data being passed in is a dict and execute the from dict constructor.我还希望 class 能够识别传入的数据是字典并执行 from dict 构造函数。

I have done my best to look up possible solutions but have come up mostly empty.我已尽最大努力查找可能的解决方案,但几乎一无所获。

Any help would be greatly appreciated.任何帮助将不胜感激。

For the simplest approach - with no additional libraries - I would personally go with a de-structuring approach via **kwargs .对于最简单的方法 - 没有额外的库 - 我个人会 go 通过**kwargs使用解构方法。

For example:例如:

>>> json = {'title': 'test', 'purchase_price': 1.2, 'shipping_price': 42, 'order_data': datetime.min}
>>> SoldItem(**json)
SoldItem(title='test', purchase_price=1.2, shipping_price=42, order_data=datetime.datetime(1, 1, 1, 0, 0))

In case of a more involved use case, such as:如果涉及更复杂的用例,例如:

  • a nested dataclass structure嵌套数据类结构
  • the input dict is the result of an API call输入字典是 API 调用的结果
  • keys in the dict are not in snake_case字典中的键不在snake_case
  • value for a key does not match annotated type for a dataclass field键的值与数据类字段的注释类型不匹配

In such cases, I would suggest third-party tools that will automagically handle this data transform for you.在这种情况下,我会建议第三方工具自动为您处理此数据转换。

For instance, the dataclass-wizard is a (de)serialization library I have come up with, for exactly this use case, ie when the input data might be coming from another source, such as the result of an API call or response.例如, dataclass-wizard是我提出的一个(反)序列化库,正是针对这个用例,即当输入数据可能来自另一个来源时,例如 API 调用或响应的结果。

It can be installed with pip :它可以用pip 安装

pip install dataclass-wizard

Usage:用法:

from dataclasses import dataclass
from datetime import datetime

from dataclass_wizard import JSONWizard


@dataclass
class SoldItem(JSONWizard):
    title: str
    purchase_price: float
    shipping_price: float
    order_data: datetime


def main():
    from pprint import pprint

    # json = requests.get(URL).json()
    json = {'title': 'test',
            'purchasePrice': '1.23',
            'shipping-price': 42,
            'Order_Data': '2021-01-02T12:34:56Z'}

    # create a `SoldItem` instance from an input `dict`,
    # such as from an API response.
    sold_item = SoldItem.from_dict(json)

    pprint(sold_item)


if __name__ == '__main__':
    main()

Prints:印刷:

SoldItem(title='test',
         purchase_price=1.23,
         shipping_price=42.0,
         order_data=datetime.datetime(2021, 1, 2, 12, 34, 56, tzinfo=datetime.timezone.utc))

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

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