13

現在、私はこのようにDTO(データ転送オブジェクト)を使用しています。

class Test1:
    def __init__(self, 
        user_id: int = None,
        body: str = None):
        self.user_id = user_id
        self.body = body

サンプル コードは非常に小さいですが、オブジェクトの規模が大きくなると、すべての変数を定義する必要があります。

掘り下げていると、python 3.7がサポートされていることがわかりましたdataclass

以下のコードは、DTO が使用するデータクラスです。

from dataclasses import dataclass


@dataclass
class Test2:
    user_id: int
    body: str

この場合、定義されていない引数をさらに渡すにはどうすればよいclass Test2ですか?

を使えばTest1簡単です。に追加**kwargs(asterisk)するだけ__init__

class Test1:
    def __init__(self, 
        user_id: int = None,
        body: str = None,
        **kwargs):
        self.user_id = user_id
        self.body = body

しかし、データクラスを使用すると、それを実装する方法が見つかりません。

ここに解決策はありますか?

ありがとう。


編集

class Test1:
    def __init__(self,
        user_id: str = None, 
        body: str = None):
        self.user_id = user_id
        self.body = body

if __name__ == '__main__':
    temp = {'user_id': 'hide', 'body': 'body test'}
    t1 = Test1(**temp)
    print(t1.__dict__)

結果 :{'user_id': 'hide', 'body': 'body test'}

ご存じのとおり、辞書型のデータを挿入したい ->**temp

データクラスでアスタリスクを使用する理由は同じです。

辞書型をクラス init に渡す必要があります。

ここにアイデアはありますか?

4

4 に答える 4

3

これは、私が使用したこれのきちんとしたバリエーションです。

from dataclasses import dataclass, field
from typing import Optional, Dict


@dataclass
class MyDataclass:
    data1: Optional[str] = None
    data2: Optional[Dict] = None
    data3: Optional[Dict] = None

    kwargs: field(default_factory=dict) = None

    def __post_init__(self):
        [setattr(self, k, v) for k, v in self.kwargs.items()]

これは次のように機能します。

>>> data = MyDataclass(data1="data1", kwargs={"test": 1, "test2": 2})
>>> data.test
1
>>> data.test2
2

ただし、データクラスは、これらの新しい属性があることを認識していないように見えることに注意してください。

>>> from dataclasses import asdict
>>> asdict(data)
{'data1': 'data1', 'data2': None, 'data3': None, 'kwargs': {'test': 1, 'test2': 2}}

これは、キーを知る必要があることを意味します。これは、私のユースケースとおそらく他のユースケースで機能しました。

于 2020-11-12T13:52:54.183 に答える