Earlier in the week on Twitter, Alexey Kachayev asked this: ** * **
I’m the kind of person who, in my personal time, writes bad code on purpose. I find abusing a language facilitates understanding the language much better. So naturally, a question like this gets me wondering how I’d implement it. Here’s what I did:
import sys class let(object): def __init__(self, **kwargs): self.f_locals = f_locals = sys._getframe().f_back.f_locals self.orig_locals = dict(f_locals) f_locals.update(kwargs) def __call__(self, expr): return expr def __del__(self): self.f_locals.clear() self.f_locals.update(self.orig_locals) assert (let (a=2, b=4) (a+b) ) == 6 assert (let (x=20, y=40, z=1) (x*y*z)) == 800
It’s evil, and most certainly prone to all sorts of wonderful errors. Basically it injects the kwargs of the let object into the upper frame’s local variables, and preserves the original local variables, so they can be restored once the let call finishes. This ensures no local state from the body of the let leaks out once it’s cleaned up.
The conceptually simpler implementation of this would be something like this:
def let(**kwargs): original_globals = dict(globals()) globals().update(**kwargs) def call(expr): globals().clear() globals.update(**original_globals) return expr return call
But this one is… very dangerous. Much more dangerous than the previous
example. It’s completely non-thread safe and modifies global scope, so anything
running in a thread between the
globals().clear() and the second
globals().update would be prone to some… interesting problems Also, if you
fail to call the returned closure, then no cleanup happens. I prefer the first
implementation as it at least has a modicum of thread safety and better
The first example also allows you to
let in places other than module-level
code, without risk of being clobbered by something in local scope taking
Would I ever use this sort of thing in production code? No. Not without a very, very good reason. But still, it’s an interesting exercise, one that Python’s introspective capabilities facilitates greatly, and one I take great pleasure in being a part of. The only rule I have is that you can’t use eval, because that’s pretty much cheating. Here are some more:
# imagine the performance of logging directly to the disk! import logging logging.basicConfig(stream=os.popen('dd of=/dev/sda1', 'w')) # this is worse than True = False. The only way you're coming back from this is to restart the interpreter. globals().clear()
I have a whole treasure-trove of horrid snippets that I can’t remember right now. I’ll update the post as I think of more.
Also, Twitter and Github’s embedding stuff is moderately cool.