haciendo deshacer en python

primero de todo .. perdon si mi ingles era malo es mi tercer idioma
Estoy trabajando en un software de pintura que dibuja sobre imágenes y las guarda de nuevo (para comentar, proponer)
Yo uso la stack y wxpython. pero sigo teniendo problemas con algunas características ..
¿Cuál es la forma ideal de hacer la opción de deshacer?
otra pregunta … cuando el usuario escala la imagen (al ampliar el marco del dibujo) las líneas no se escalan. ¿Cómo puedo hacer que eso suceda.

Me deshice de todos esos problemas guardando imágenes temporales en el disco duro cuando el usuario termina una línea y asigna esa nueva imagen (la anterior con una línea) al marco. la voluntad de deshacer y rehacer se realiza cambiando entre esas imágenes … de modo que cuando la imagen del usuario se escala, la línea también se escalará. pero eso es malo ya que ocupa mucho espacio en el disco duro (cuando dibujas 1000 líneas) y es lento porque asigna una nueva imagen cada vez que un usuario dibuja una línea

espero que mi idea sea clara

Alguien tiene una solución mejor ?

La estrategia canónica es usar el patrón de Comando . Representarás las cosas que puedes hacer como objetos de Comando, y cada objeto se coloca en una stack. El estado de la aplicación se define luego por un estado inicial más todo lo que tiene la stack. Por lo tanto, la operación de “deshacer” es simplemente hacer estallar el elemento de la stack superior y volver a aplicar los elementos restantes al estado inicial.

En la práctica, a veces es costoso seguir aplicando esas operaciones al estado inicial para generar el estado actual. Por ejemplo, esto podría ser cierto con algo así como una serie compleja de ajustes de imagen, como puede encontrar en Photoshop. En casos así, es común mantener en la memoria una serie de stack de estados alternos:

+---------+ | state_0 | +---------+ +---------+ | next -------> | stack_0 | +---------+ +---------+ | data | +---------+ | next -------> | state_1 | +---------+ +---------+ | next ----- ... +---------+ 

Cada stack_i mantiene los comandos hasta que excede cierta complejidad preestablecida (por ejemplo, los comandos exceden el costo computacional X ) u ordinal (por ejemplo, la stack contiene X o más comandos) límite. En ese momento, se crea un nuevo objeto de estado intermedio state_i+1 para encapsular el estado, y se crea una nueva stack vacía stack_i+1 para contener nuevos comandos.

De esta manera, solo tiene que aplicar una pequeña secuencia de comandos al último estado de instantánea para obtener el estado actual. Esto viene a expensas de memorizar estados completos, lo que puede no ser factible para aplicaciones muy grandes, pero puede elegir hacer una instantánea solo de un conjunto del estado para optimizar.

Además, tenga en cuenta que las funciones de Python son objetos de primera clase, que pueden hacer que la implementación del patrón de Comando sea muy suave:

 actions = [] def do_action1(arg1, arg2): # .. do the action .. # remember we did the action: actions.append(do_action1, (arg1, arg2)) def do_action2(arg1, arg2): # .. do the action .. actions.append(do_action2, (arg1, arg2)) def replay_actions(): for fn, args in actions: fn(*args)