我正在設計一個面向對象的數據結構,從用戶的角度來看應該很簡單,例如通過方法鏈接(又名Fluent interface)。但是,每個更改只應在對象上暫時執行:在該鏈中,但不超出該鏈。
下面是一個簡單的例子,做不工作像預期一樣:在方法鏈接過程中臨時保留對對象的更改
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)
在這種情況下,.add()
使得永久變化number
。然而,永久性的變化只可能是這樣的:
# 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
然而,實際工作中類和對象與我的工作包含大量的數據,屬性,方法,甚至子類。所以我們應該避免在每一種方法中拷貝實例,除了它涉及醜陋的代碼。
有沒有辦法解決這個問題,通過(靜靜地)在鏈的第一個元素上創建一個副本一次?或者通過摧毀鏈條末端所做的任何更改? (需要注意的是現實世界的「變化」涉及許多不同,可交換不僅僅是增加數量等方法)
接受的解決方案應該執行必要的操作內部,即不打擾用戶界面:
# These are NOT accepted solutions:
number.copy().add(4).add(12)
number.add(4).add(12).undo()
如果除了自我複製之外沒有其他直接的解決方案,問題將會是:這樣做的最優雅的方式是維持代碼可讀性並保持內存使用率低的最優方法是什麼?例如,通過自我複製功能來裝飾每種類別的方法?
我不明白該對象如何自動檢測「臨時範圍」的結束 - 除非可能通過編寫自己的基於python的語言,甚至是...... FWIW,所有「流暢的接口「到目前爲止,我所看到的實現方式都是對對象進行變異或返回副本。 –