Live data from Hacker News

Python 3's F-Strings: An Improved String Formatting Syntax

realpython.com

71–80 of 147 posts

Re: Python 3's F-Strings: An Improved String Formatting Syntax

#71
post #2

I can't say I like the f" syntax much. I think JS's backtick is better. Other than that, I agree, much better than % and less verbose than .format. It's just the f" or f' that doesn't sit right with me

I've put together a proposal to have all strings be f-strings by default. Then you could drop the "f" prefix. I also propose adding a "p" prefix (for "plain") to remove the f-string parsing behavior. I talked about it at the last Python core sprint, and it only got lukewarm support, so I'm not sure I'm going to pursue it.

> I've put together a proposal to have all strings be f-strings by default.

Please, no.

I mean, it would be a breaking change, which needs a really compelling case, will make all introductory material wrong, and...offers what benefit?

Re: Python 3's F-Strings: An Improved String Formatting Syntax

#72
post #2

I can't say I like the f" syntax much. I think JS's backtick is better. Other than that, I agree, much better than % and less verbose than .format. It's just the f" or f' that doesn't sit right with me

I've put together a proposal to have all strings be f-strings by default. Then you could drop the "f" prefix. I also propose adding a "p" prefix (for "plain") to remove the f-string parsing behavior. I talked about it at the last Python core sprint, and it only got lukewarm support, so I'm not sure I'm going to pursue it.

I think that would be a pretty serious harm to Python as a language. When I was learning Python, I was using PHP, which has $ interpolation for double quoted strings but not single quotes. I didn’t understand how PHP worked at all and it really confused me. In retrospect, I don’t know why it was so hard to wrap my head around, but it was. Learning Python was liberating because I knew exactly when and how interpolation would take place. The decision not to follow the lead of Perl and Bash and auto-interpolate was made deliberately by Guido many years ago. It would be a shame to go back on that decision now.

Re: Python 3's F-Strings: An Improved String Formatting Syntax

#73
post #70

A wart is the standard logging module, which uses %-style strings. For example: log.debug("Unexpected, got %r", (got,)) By doing it this way, it can defer rendering the string until it is actually needed, which is (assumed to be) a win when the logging module is normally just going to toss the low level messages away rather than emit them anywhere. I think you lose this optimization if you use f-strings. I don't thin…

Whilst percent strings can't, calls to format can.

So:

    log.debug("Unexpected, got {got}".format(got=got))
Or, to just use the available locals to automatically fill that in for you:

    log.debug("Unexepected, got {got}".format(**locals()))
Or if you want both globals and locals with a preference for locals:

    log.debug("Unexepected, got {got}".format(**{**globals(), **locals()}))

Re: Python 3's F-Strings: An Improved String Formatting Syntax

#74
post #44

I learned this nice syntax from a tweet yesterday: >>> import datetime >>> now = datetime.datetime.now() >>> f"Today is {now:%m/%d/%Y}." 'Today is 01/20/2021.' No need for now.strftime() in simple string output! https://twitter.com/mariatta/status/1351359518316216321

Thank you! This was literally what I opened the article for (I'd seen the f syntax previously but hadn't paid much attention) and it's conspicuously missing!

Re: Python 3's F-Strings: An Improved String Formatting Syntax

#75
post #14
post #2

I can't say I like the f" syntax much. I think JS's backtick is better. Other than that, I agree, much better than % and less verbose than .format. It's just the f" or f' that doesn't sit right with me

I think you are right to prefer JS's backtick notation, but not in your reason. The main problem with python's f" syntax is that it's just a very complex, non-extensible hack whereas in javascript you can prefix a tag to specify how the interpolation happens. Instead of this, f-strings have a lot of hardcoded and often broken behavior which can't be fixed let alone customized. For example, you can specify a field wid…

Yes. Python in general has gone from being “executable pseudo code” to a series of complex language design trade offs largely because it had failed to grasp the right abstractions in its evolution. Backtick functions in JS are so powerfully clever and basically impossible to recreate in Python.

Re: Python 3's F-Strings: An Improved String Formatting Syntax

#76
post #70

A wart is the standard logging module, which uses %-style strings. For example: log.debug("Unexpected, got %r", (got,)) By doing it this way, it can defer rendering the string until it is actually needed, which is (assumed to be) a win when the logging module is normally just going to toss the low level messages away rather than emit them anywhere. I think you lose this optimization if you use f-strings. I don't thin…

Also, remember that the first argument to the logging functions is considered to be a format string. So using f-strings is not just less efficient, it is also not robust, unless you do:

    logging.debug("%s", f"Unexpected, got {got}")
because otherwise, if the format string is the first/only argument, and `got` unexpectedly contain `%`, an exception will be raised due to a missing format parameter.

(Also, for the logging functions, you don't pass a tuple, just a normal series of arguments.)

Re: Python 3's F-Strings: An Improved String Formatting Syntax

#77
post #70

A wart is the standard logging module, which uses %-style strings. For example: log.debug("Unexpected, got %r", (got,)) By doing it this way, it can defer rendering the string until it is actually needed, which is (assumed to be) a win when the logging module is normally just going to toss the low level messages away rather than emit them anywhere. I think you lose this optimization if you use f-strings. I don't thin…

logging.Formatter defaults to working with %-style strings but it it can be configured to use the {}-style of str.format. (As of 3.2)

You still miss out on the scoping of f-strings, and embedding function calls. But passing around what amounts to an "eval" expression is a footgun that should obviously be frowned upon.

There's also an option for $-style Template strings. But I can't recall when I've ever seen someone use that.

Re: Python 3's F-Strings: An Improved String Formatting Syntax

#78
From reading the comments in the discussion here, I'm curious why the f-string syntax is so all-over-the-place?

  - f"{foo}" uses the default format
  - f"{foo!r}" uses repr to format
  - f"{foo=}" uses a special-cased debugging introspection
  - f"{foo:formatstr}" uses the default format with a custom format string
  - f"{foo:{bar}}" uses a dynamic format string
It seems like `!r` and `=` should have been implemented with `:r` and `:=` instead?

Re: Python 3's F-Strings: An Improved String Formatting Syntax

#80
post #70

A wart is the standard logging module, which uses %-style strings. For example: log.debug("Unexpected, got %r", (got,)) By doing it this way, it can defer rendering the string until it is actually needed, which is (assumed to be) a win when the logging module is normally just going to toss the low level messages away rather than emit them anywhere. I think you lose this optimization if you use f-strings. I don't thin…

logging.Formatter defaults to working with %-style strings but it it can be configured to use the {}-style of str.format. (As of 3.2) You still miss out on the scoping of f-strings, and embedding function calls. But passing around what amounts to an "eval" expression is a footgun that should obviously be frowned upon. There's also an option for $-style Template strings. But I can't recall when I've ever seen someone…

> In Python 3.2, the Formatter gained a style keyword parameter which, while defaulting to % for backward compatibility, allowed the specification of { or $ to support the formatting approaches supported by str.format() and string.Template. Note that this governs the formatting of logging messages for final output to logs, and is completely orthogonal to how an individual logging message is constructed.

The style option only applies to the outer format applied by the formatter (timestamp, level, file, line, etc), it does not apply to the logging calls.

Post reply on HN