[Python-ideas] Briefer string format

Eric V. Smith eric at trueblade.com
Mon Jul 20 16:19:34 CEST 2015


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 at 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 at 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.



More information about the Python-ideas mailing list