compact() and extract() are functions in PHP I find tremendously handy. compact() takes a list of names in the symbol table and creates a hashtable with just their values. extract does the opposite. e.g.,
$foo = 'what'; $bar = 'ever'; $a = compact('foo', 'bar'); $a['foo'] # what $a['baz'] = 'another' extract(a) $baz # another
Is there a way to do the same in Python? I’ve looked all around and the closest I’ve come is this thread, which seems to frown on it.
I know about locals(), globals() and vars(), but how can I handily select just a subset of their values?
Does Python have something even better that obviates the need for this?
Advertisement
Answer
It’s not very Pythonic, but if you really must, you can implement compact()
like this:
import inspect def compact(*names): caller = inspect.stack()[1][0] # caller of compact() vars = {} for n in names: if n in caller.f_locals: vars[n] = caller.f_locals[n] elif n in caller.f_globals: vars[n] = caller.f_globals[n] return vars
It used to be possible to implement extract()
like this, but in modern Python interpreters this doesn’t appear to work anymore (not that it was ever “supposed” to work, really, but there were quirks of the implementation in 2009 that let you get away with it):
def extract(vars): caller = inspect.stack()[1][0] # caller of extract() for n, v in vars.items(): caller.f_locals[n] = v # NEVER DO THIS - not guaranteed to work
If you really feel you have a need to use these functions, you’re probably doing something the wrong way. It seems to run against Python’s philosophy on at least three counts: “explicit is better than implicit”, “simple is better than complex”, “if the implementation is hard to explain, it’s a bad idea”, maybe more (and really, if you have enough experience in Python you know that stuff like this just isn’t done). I could see it being useful for a debugger or post-mortem analysis, or perhaps for some sort of very general framework that frequently needs to create variables with dynamically chosen names and values, but it’s a stretch.