pre render script behaviour I use simple python snippets to replicate the light pass manager (LPM) script's behaviour for 3dsmax link.

LPM in 3dsmax basically just runs a pre_render script that applies overrides and then renders.  

Blender can do the same thing with 
bpy.app.handlers.render_pre

It works alright, but there is one essential thing that doesnt work as I expected it:  

-in 3dsmax, the pre_render_script is only run on the data that is sent to the renderer. The scene in front of the user is unchanged.

-in Blender, the pre_render_script is run on the scene before it is sent to the renderer. Therefore, after rendering, the scene in the viewport has all changes applied and the original state of the scene is lost. 

I dont want to write scripts that record the whole state of the scene so it can be rebuilt post render. It is error-prone, needs to be maintained, I am a python noob and besides that, Blender has all the data already stored in the file. 

My workaround right now
start the render as a subprocess and run the python script that sets the overrides:

render_cmd = '''\
gnome-terminal -- 
/usr/bin/blender -b 
%s 
--python %s
-S Scene -s 1 -e 1 -a
''' % (fname, render_prep_script_name)
subprocess.call(render_cmd.split())


This is not bad, I can work with that. But I have to wait for the renderer to save the output image before I can see it. 
So I am wondering, should the behaviour of the render_pre handler not be different?
The 3ds Max script must be using a copy of the data, if the data sent to the renderer is editable, but still independant of the scene.

There are a couple of other workaround I can think of.


Make a copy of the scene. Then use your python script on the copy and render it. You can delete the copy on render_post or just overwrite the scene everytime you start rendering. This will need a little bit more RAM, but no graphical memory if executed in background mode.
The above solution can be improved by making a linked copy (LINK_OBJECTS). It will not take up much more memory, since the data blocks the same. Then (on the copy) make the datablocks you want to change single users and change them.
Build an operator with UNDO activated and register it. Then, in your python script, call the operator (which does the changes), render the scene, then undo it. Depending on your scene, this may not be faster than a full copy, but will consume less RAM (I think).
Execute your python script from another empty Blender file. Append the scene (which you want to render). Make the changes, and render it, then delete it. Repeat. This is similiar to your setup, but could use the same background blender instance.
The above solution can be improved, by only removing and then appending objects which are changed by the python script.