私は、メソッドチェインのように(例えば、Fluent interface)、ユーザーの観点から扱いやすいオブジェクト指向のデータ構造を設計しています。ただし、各変更はオブジェクト上で一時的にのみ実行する必要があります。そのチェーン内で、そのチェーンを超えないでください。 .add()
はnumber
から永久変更を行い、この場合メソッドチェーン中にオブジェクトを一時的に変更する
class C:
def __init__(self, num):
self.sum = num
def add(self, num=0):
self.sum += num
return self
number = C(23)
number.add(7).add(12).sum
# 42
number.sum
# 42 (but I expect: 23)
:
ここで意図したとおりない作業を行う簡略化した例です。ただし、恒久的な変更は、次のように可能なはずです:一時的範囲で
# This is the only way how a user should make permanent changes:
number = number.add(4).add(12)
は、私はチェーンが終了した後、バックnumber
の古いバージョンを取得する方法を探しています。でも、
class C2:
def __init__(self, num):
self.sum = num
def add(self, num=0):
self2 = C2(self.sum) # or equivalently: self2 = copy.deepcopy(self)
self2.sum += num
return self2
number = C2(23)
number.add(7).add(12).sum
# 42
number.sum
# 23
は、しかし、私が働いているとactuallクラスとオブジェクトは、データの膨大な量を含む、属性メソッド、および:絶望の端に、私は、「インスタンスの複製」のような醜いソリューションを考えることができますサブクラス。したがって、醜いコードが含まれているという事実の他に、すべてのメソッドでインスタンスをコピーしないようにする必要があります。
この問題を解決する方法はありますか?チェーンの最初の要素で1回だけコピーを作成する(サイレントに)?またはチェーンの最後に加えられた変更を破棄することによって、
:Anはソリューションは、ユーザーインターフェイスを悩ませずに、必要な操作 内部、すなわちを実行する必要が受け入れ (現実世界「変化」は数字だけを追加する以外の多くの異なる、通勤方法を含むことに注意してください)# These are NOT accepted solutions:
number.copy().add(4).add(12)
number.add(4).add(12).undo()
自己複製以外の直接的な解決策がない場合は、次のような質問があります。コードを読みやすくし、メモリ使用量を低く抑える最も洗練された方法は何ですか?たとえば、自己複製機能によってすべてのクラスメソッドをデコレートしますか?
私は、オブジェクトが "一時的な範囲"の終わりを自動的に検出する可能性があるとは思わない - おそらくあなた自身のPythonベースの言語を書くことを除いては... FWIW、すべての "流暢なインターフェイス私が今までに見た実装は、オブジェクトを所定の場所に変更したり、コピーを返すことができます。 –