dataclass インスタンスの属性を置き換えたいのですが、これはnamedtuple._replace()
に類似しています。つまり、元のオブジェクトの変更されたコピーを作成します。
from dataclasses import dataclass
from collections import namedtuple
U = namedtuple("U", "x")
@dataclass
class V:
x: int
u = U(x=1)
u_ = u._replace(x=-1)
v = V(x=1)
print(u)
print(u_)
print(v)
これは次を返します:
U(x=1)
U(x=-1)
V(x=1)
データクラスオブジェクトでこの機能を模倣するにはどうすればよいですか?
Pythonデータクラスモジュールには、データクラスインスタンスのフィールド置換用のパブリックAPIがあり、文書化されています ここ 。この機能は、モジュールレベルのヘルパー関数によって提供されます。
from dataclasses import replace
使用法はcollections.namedtuple
とは異なります。この機能は、生成された型のメソッドを介して提供されていました(補足:namedtuple._replace
は文書化/公開されています。この名前の選択は、作成者によって「後悔」と呼ばれていました。回答の最後にあるリンクを参照してください)。
使用例:
>>> from dataclasses import dataclass, replace
>>> @dataclass
... class V:
... x: int
... y: int
...
>>> v = V(1, 2)
>>> v_ = replace(v, y=42)
>>> v
V(x=1, y=2)
>>> v_
V(x=1, y=42)
設計の背景については、PyCon 2018のトークを参照してください- データクラス:すべてのコードジェネレーターを終了するコードジェネレーター 。 replace
APIについては、namedtuple
とdataclasses
の間の他の設計上の違い、およびいくつかのパフォーマンスの比較とともに、詳細に説明されています。
dataclass
は、特別な__init__
メソッドと、型注釈付き属性に基づく他の「ボイラープレート」メソッドのホストを自動的に作成するための単なる構文糖衣です。
クラスが作成されると、他のクラスと同じようになり、その属性を上書きしたり、インスタンスをコピーしたりできます。
import copy
v_ = copy.deepcopy(v)
v_.x = -1
属性が何であるかに応じて、copy.copy
のみが必要になる場合があります。