How do I stop vertex normals getting overwritten when I enter edit mode?
You want to use Mesh.normals_split_custom_set(normals).

Custom normals are always set per loop (i.e. face corners), but this utility set those per-vertex (it internally translates those 'vert normals' to loop ones).

Note that you have to set all normals for all vertices at once (basically because this is a rather heavy process, so setting it by vertex or loop would be inefficient), however you can set some normals to zero (0.0, 0.0, 0.0) vector to keep existing custom normals, or use default auto-computed ones.

Finally, you must be in Object mode currently, custom normals at BMesh level (Edit mode) are not yet supported really.

You can find some examples of that API in use in the new mesh_custom_normals_tools.py addon, as well as OBJ and FBX importers.