If you want to do the same without modifying the script (or if you have the script already running without the needed import for the remote debugging possibility), i.e. inject into a running process:
I use ipython's "ipdb" or plain old Python "pdb" for the same functionality, and a bit more -- people don't seem to realize that ipdb gives them a full-on REPL within the calling context.
I usually wrap it into our error logging functions, so an environment variable enables debugging where I would normally have a catch-all -- very handy when looking for heisenbugs in AndBug.
My most excellent friend Thomas Hurst implemented a remote python shell a few years ago, for use in debugging running instances of Terminator.
You can see the code in question here:
As the readme notes, it's completely unsafe if you perform any mutation operation.
As to the performance hit, I'd expect almost none when not in use for long-running processes: it spawns a thread, and that thread will then wait on a socket accept, no connection, no resources spent. You'll still be paying in memory for the server thread, but that's it (the server thread only creates two objects, an rlcompleter.Completer instance and a function).
We've been using rfoo to do this. It doesn't seem to impact performance when you're not using it. When you are using it, it's unsafe if you do unsafe things. We primarily use it for debugging by passively inspecting the messed-up portion of the server's state.
Objective-C also has Cycript at http://cycript.org/, which has a hybrid syntax of JavaScript and Objective-C and supports injecting into any running process.b
https://github.com/albertz/pydbattach