[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):
self.values.append(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')
logger.flush()
produces:
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}}'.
Eric.
More information about the Python-Dev
mailing list