
On 07/20/2015 10:08 AM, Ryan Gonzalez wrote:
I would prefer something more like:
def f(s): caller = inspect.stack()[1][0] return s.format(dict(caller.f_globals, **caller.f_locals))
You need to use format_map (or **dict(...)). And ChainMap might be a better choice, it would take some benchmarking to know. Also, you don't get builtins using this approach. I'm using eval to exactly match what evaluating the variable in the parent context would give you. That might not matter depending on the actual requirements. But I agree there are multiple ways to do this, and several of them could be made to work. Mine might have fatal flaws that more testing would show. Eric.
On July 20, 2015 8:56:54 AM CDT, "Eric V. Smith" <eric@trueblade.com> wrote:
On 07/19/2015 07:35 PM, Mike Miller wrote:
Hi,
Ok, I kept the message brief because I thought this subject had previously been discussed often. I've expanded it to explain better for those that are interested.
---
Needed to whip-up some css strings, took a look at the formatting I had done and thought it was pretty ugly. I started with the printf style, and had pulled out the whitespace as vars in order to have a minification option:
csstext += '%s%s%s{%s' % (nl, key, space, nl)
Decent but not great, a bit hard on the eyes. So I decided to try .format():
csstext += '{nl}{key}{space}{{{nl}'.format(**locals())
This looks a bit better if you ignore the right half, but it is longer and not as simple as one might hope. It is much longer still if you type out the variables needed as kewword params! The '{}' option is not much improvement either.
csstext += '{nl}{key}{space}{{{nl}'.format(nl=nl, key=key, ... # uggh csstext += '{}{}{}{{{}'.format(nl, key, space, nl)
Disclaimer: not well tested code.
This code basically does what you want. It eval's the variables in the caller's frame. Of course you have to be able to stomach the use of sys._getframe() and eval():
####################################### import sys import string
class Formatter(string.Formatter): def __init__(self, globals, locals): self.globals = globals self.locals = locals
def get_value(self, key, args, kwargs): return eval(key, self.globals, self.locals)
# default to looking at the parent's frame def f(str, level=1): frame = sys._getframe(level) formatter = Formatter(frame.f_globals, frame.f_locals) return formatter.format(str) #######################################
Usage: foo = 42 print(f('{foo}'))
def get_closure(foo): def _(): foo # hack: else we see the global 'foo' when calling f() return f('{foo}:{sys}') return _
print(get_closure('c')())
def test(value): print(f('value:{value:^20}, open:{open}'))
value = 7 open = 3 test(4+3j) del(open) test(4+5j)
Produces: 42 c:<module 'sys' (built-in)> value: (4+3j) , open:3 value: (4+5j) , open:<built-in function open>
Eric.
------------------------------------------------------------------------
Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- Sent from my Android device with K-9 Mail. Please excuse my brevity.