[Python-Dev] PEP-498: Literal String Formatting

Eric V. Smith eric at trueblade.com
Mon Aug 10 03:02:09 CEST 2015

On 8/9/2015 8:24 PM, Peter Ludemann wrote:
> What if logging understood lambda? (By testing for types.FunctionType).
> This is outside PEP 498, but there might be some recommendations on how
> "lazy" evaluation should be done and understood by some functions.
> e.g.:
> log.info <http://log.info>(lambda: f'{foo} just did a {bar} thing')
> It's not pretty, but it's not too verbose. As far as I can tell, PEP 498
> would work with this because it implicitly supports closures — that is,
> it's defined as equivalent to
> log.info <http://log.info>(lambda: ''.join([foo.__format__(), ' just did
> a ', bar.__format__(), ' thing']))

That basically works:
class Foo:
    def __init__(self, name):
        self.name = name

    def __format__(self, fmt):
        print(f'__format__: {self.name}')
        return f'{self.name}'

class Logger:
    # accumulate log messages until flush is called
    def __init__(self):
        self.values = []

    def log(self, value):

    def flush(self):
        for value in self.values:
            if callable(value):
                value = value()
            print(f'log: {value}')

logger = Logger()

f1 = Foo('one')
f2 = Foo('two')
print('before log calls')
logger.log('first log message')
logger.log(lambda:f'f: {f1} {f2}')
logger.log('last log message')
print('after log calls')
f1 = Foo('three')


before log calls
after log calls
log: first log message
__format__: three
__format__: two
log: f: three two
log: last log message

But note that when the lambdas are called, f1 is bound to Foo('three'),
so that's what's printed. I don't think that's what the logging module
would normally do, since it wouldn't see the rebinding.

I guess you'd have to change logging to do something special if it had a
single argument which is a callable, or add new interface to it.

And of course you'd have to live with the ugliness of lambdas in the
logging calls.

So, I can't say I'm a huge fan of the approach. But writing examples
using f-strings is way more fun that using %-formatting or str.format!

But it does remind me I still need to implement f'{field:{width}}'.


More information about the Python-Dev mailing list