[Tutor] The Best Way to go About with Self Modifying Code/Code Generation?

Steven D'Aprano steve at pearwood.info
Sun Jul 8 15:48:59 CEST 2012


Aaron Tp wrote:
> 
> Hey all, I have a question on using self-modifying code/code generation in Python;
> namely how to do it. 

I know others have already said not to do this, and to be honest I was going 
to say that same thing, but I have changed my mind. Buggrit, this is Python, 
where we are all consenting adults and you're allowed to shoot yourself in the 
foot if you want.

"Writing self-modifying code" actually covers a large range of techniques, 
ranging from the simple and straight-forward use of conventional factory 
functions, to the completely crazy self-modifying source code. There's a lot 
to learn. Rather than try to cover it all, I'll sketch out the various things 
you should learn about before you can make self-modifying code.

Obviously basic Python skills, how to read and write files, import modules, 
etc. That's the boring part, and I'm going to assume you know all that. If you 
don't, do a few tutorials and then come back.

Still here? Cool! On to the hard part. But first, beware:

     HERE BE DRAGONS


As fans of the British fantasy author Terry Pratchett all know, there are two 
types of dragons, swamp dragons and Draco nobilis, the noble dragon.

Swamp, or common, dragons are small, mostly harmless, with a very finicky 
digestive system and a regrettable tendency to blow up, but with a little bit 
of care and attention that can be occasionally useful.

The noble dragon, on the other hand, are huge, cunning, cruel, malicious, and 
anything but harmless. They don't so much blow up as silently fly down out of 
the sky and vapourize you with white-hot flame. They are best avoided by 
anyone other than experts. Actually, even experts should avoid them.

Writing self-modifying code is like dealing with dragons. And like dealing 
with dragons, you should start off with the fairly harmless variety before 
moving up to the more tricky type.

So start with this simple example of self-modifying code:

http://code.activestate.com/recipes/68429-ring-buffer/

This is probably as harmless and simple as self-modifying code can get: you 
have an instance which dynamically changes it's own class as it goes, so as to 
change its behaviour. Other languages might choke on this, but for Python, 
this counts as trivial.

If this example confuses you, if it's too hard for you to understand how it 
works, then you're not ready to try dragon taming. Learn some more Python 
first before you get into self-modifying code. We can help you with that.


Other simple techniques to start with include:

- dynamic code generation with factory functions and closures

- shadowing globals, built-ins or modules with your own code

- rebinding methods, functions or classes at runtime

- monkey-patching builtin functions

- functions or methods which rebind *themselves* at runtime


Feel free to ask for help on any of these. Or google on key phrases such as 
"monkey-patching", "shadowing builtins", "factory function", "closure".


So far, this all counts as the easy, conservative side of self-modifying code. 
Factory functions are even staid and boring. Shadowing is sometimes useful. 
Even monkey-patching, which is what those craz-ee Ruby hackers do, is almost 
respectable. Respectable like drinking two bottles of gin before going 
fox-hunting -- everybody knows you shouldn't do it, but if you survive the 
first time, you start to think nothing could possibly go wrong.

Be warned that "easy" is relative -- these can actually be fairly advanced 
techniques, and are tricky to get right and difficult to debug when they go 
wrong. And things *will* go wrong. Remember the warnings from the creator of 
the Unix operating system, Brian Kernighan:

     "Everyone knows that debugging is twice as hard as writing a
     program in the first place. So if you’re as clever as you can
     be when you write it, how will you ever debug it?"

     "Debugging is twice as hard as writing the code in the first
     place. Therefore, if you write the code as cleverly as possible,
     you are, by definition, not smart enough to debug it."


Okay. You've got your handgun, you're ready to shoot your own foot.
Once you've learned to tame the swamp dragons of runtime rebinding, 
monkey-patching and dynamic code generation, you're ready to move up to the 
next, slightly more radical, stage: eval and exec.

Here are some links to get you started:

http://lucumr.pocoo.org/2011/2/1/exec-in-python/
http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
http://code.activestate.com/recipes/500261-named-tuples/


Still got all your toes? Excellent. Now you *might* be ready to go after the 
*really* big dragons:

- AST manipulation

http://www.dalkescientific.com/writings/diary/archive/2010/02/22/instrumenting_the_ast.html
http://docs.python.org/library/ast.html


- byte code hacks

http://nedbatchelder.com/blog/200804/wicked_hack_python_bytecode_tracing.html
http://wiki.python.org/moin/ByteplayDoc
http://code.activestate.com/recipes/498242/
http://www.voidspace.org.uk/python/weblog/arch_d7_2006_11_18.shtml#e553


- source code self-modification

http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=44953
http://thedailywtf.com/Articles/Self-Modifying-VBA.aspx

And now you are ready for Mel.

http://www.catb.org/jargon/html/story-of-mel.html


Have fun!



-- 
Steven


More information about the Tutor mailing list