Что вам не хватает, так это то, что lst[:]
является только мелкой копией. Новый список, возвращаемый , может содержать и добавлять элементы без изменения исходного списка , но ссылки, содержащиеся в списке, по-прежнему доступны. Так что изменение элемента, скажем original_list[1].fooBar()
, повлияет как на ссылку , содержащуюся в первоначальном списке и в новом списке, так как они являются одинаковыми ссылка.
Вы должны смотреть на использование deepcopy()
(см copy modules's Python docs) - однако, что приходят с это собственный набор вопросов (объекты, которые не поддерживают его, копирование слишком много, и т.д.).
В вашем случае это, вероятно, означает, что history('add', lst[:])
действительно должно быть что-то вроде: history('add', copy.deepcopy(lst))
.
Похоже, что есть и другие проблемы с вашим примером. Вы, вероятно, не хотите создавать копии все время, но как только один раз, когда он войдет в эту историю и, вероятно, снова, когда она уйдет? Я не уверен, я понимаю реальной проблемы, так что это может быть бедным советом, но я бы ожидать, что код будет более как:
def history(function, toAdd):
global history1
global history2
global history3
global history4
global history5
if function == 'add':
history5 = history4
history4 = history3
history3 = history2
history2 = history1
history1 = copy.deepcopy(toAdd)
elif function == 'undo':
toReturn = history1
history1 = history2
history2 = history3
history3 = history4
history4 = history5
# Should history5 still be valid at this point? Maybe do?
# history5 = None
# There could be several issues here. Remember, this is a deep copy
# of a previous object/collection. If your code is expecting the
# original object, you will not have it.
return toReturn
elif function == 'return':
# Is it expected that whomever calls this will receive a copy that
# they can manipulate? If so, the deepcopy() here is required.
return copy.deepcopy(history1)
Я оставил некоторые примечания рядного выше, где я думаю, вы должны беспокоиться о вещах . Я хотел бы также рассмотреть вопрос об упрощении этого кода немного больше:
from collections import deque
_history_store = deque(maxlen=5)
def history(function, toAdd):
global _history_store
if function == 'add':
_history_store.append(copy.deepcopy(toAdd))
elif function == 'undo':
if _history_store:
return _history_store.pop()
# No history to return.
return None
elif function == 'return':
if _history_store:
return copy.deepcopy(_history_store[-1])
# No history to return.
return None
Использование Deque поможет сохранить колпачок размера на 5 записей, без необходимости делать всех перетасовки себя.
Добро пожаловать в SO! Сделайте минимальные примеры и скажите на своем названии * как * он не ведет себя так, как ожидалось. :-) –
Вы знаете, что вы можете использовать один список для своего подхода вместо 5 переменных? Они поддерживают 'append (item)' и 'pop()'. –