Я проектирую объектно-ориентированную структуру данных, которая должна быть прост в обращении с точки зрения пользователя, например, путем цепочки (aka 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
Однако классы actuall и объекты, с которыми я работаю, содержит огромное количество данных, атрибуты, методы, и даже подклассы. Поэтому нам следует избегать копирования экземпляра в каждом отдельном методе, кроме того, что он включает в себя уродливый код.
Существуют ли способы решения этой проблемы, например. (тихо), создавая единственную копию только один раз в первом элементе цепочки? Или путем уничтожения любых изменений, сделанных в конце цепи? (Обратите внимание, что в реальном мире «изменения» включают много различных, коммутируемых других, чем просто добавление чисел методы)
обслуживаемого решение должно выполнить необходимые операции внутри, то есть, не беспокоя пользовательский интерфейс:
# These are NOT accepted solutions:
number.copy().add(4).add(12)
number.add(4).add(12).undo()
Если нет прямого решения, кроме саморепликации, вопрос будет следующим: Какой самый элегантный способ сделать это, который поддерживает считывание кода и снижает потребление памяти? Например, украшая каждый метод класса функцией самовоспроизводства?
Я не вижу, как было бы возможно, чтобы объект автоматически обнаружил конец «временной области» - за исключением, возможно, написания собственного языка на основе python и даже тогда ... FWIW, весь «свободный интерфейс» «Реализации, которые я видел до сих пор, либо мутируют объект на месте, либо возвращают копию. –