[Python-ideas] Briefer string format

Eric V. Smith eric at trueblade.com
Mon Jul 20 15:56:54 CEST 2015


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.




More information about the Python-ideas mailing list