f-strings put the value in the output string exactly where the value should be. Massive win for contextual awareness, no need to count ...3, 4, okay what's the position 4 value over on the right, does it match up?? And they use classic Python string formatting commands, except the = operator which makes them even better with a "name the variable, show its value in a concise way" option. What's not to like?
(And if you don't like them, uh...they're not mandatory. Just don't use them.)
> This PEP is driven by the desire to have a simpler way to format strings in Python.
I think f-strings have become the thing they were trying to replace and they are now more complicated than the old % interpolation.
I still like f-strings and use them a lot but if you look at the cheat sheet, they are no longer simple.
ayhanfuat 5 hours ago [-]
> if you look at the cheat sheet, they are no longer simple.
Most of the formatting options in the cheat sheet have always been available with f-strings. They are part of the Format Specification Mini Language (https://docs.python.org/3/library/string.html#format-specifi...) and both string.format and f-strings use the same spec. f-strings have some additional capabilities like inline expressions and debugging/logging with `=`.
disgruntledphd2 1 hours ago [-]
The equals addition is basically the best thing ever, I almost always use it for logging. Incredibly helpful (for me, at least).
lynnharry 2 hours ago [-]
I don't think "simple" here means lack of functions. It means more intuitive and simpler code, and easier curve of learning. And to me f-string is very simple.
roenxi 5 hours ago [-]
This looks like a cheatsheet for writing a hard-to-read Python script. I don't know who gets karmic brownie points for a f"{string:>20}" field, but under most normal cases it'd be better to use rjust() directly and not force people to remember Yet Another DSL.
Once a reader could be reasonably expected to consult reference material while working out what a print() is doing something has gone wrong. This is the programmer equivalent of wearing too much makeup.
cloudbonsai 4 hours ago [-]
You haven't seen the full depth yet. Suppose that you encountered with this line:
g - General format. For a given precision p >= 1, this rounds the number to p significant digits and then formats the result in either fixed-point format or in scientific notation, depending on its magnitude. A precision of 0 is treated as equivalent to a precision of 1.
The precise rules are as follows: suppose that the result formatted with presentation type 'e' and precision p-1 would have exponent exp. Then, if m <= exp < p, where m is -4 for floats and -6 for Decimals, the number is formatted with presentation type 'f' and precision p-1-exp. Otherwise, the number is formatted with presentation type 'e' and precision p-1. In both cases insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it, unless the '#' option is used.
With no precision given, uses a precision of 6 significant digits for float. For Decimal, the coefficient of the result is formed from the coefficient digits of the value; scientific notation is used for values smaller than 1e-6 in absolute value and values where the place value of the least significant digit is larger than 1, and fixed-point notation is used otherwise.
Positive and negative infinity, positive and negative zero, and nans, are formatted as inf, -inf, 0, -0 and nan respectively, regardless of the precision.
Make sense? You now should be able to see why it's called f-string.
jgtrosh 3 hours ago [-]
Yes, it's a generalisation of `%g` in f-string's ancestor printf(3). This is what people expect to find in formatting templates.
ilovetux 3 hours ago [-]
I love python f-strings. I dont use the format specifiers that this article points out.
Also, even though use in log messages is discouraged, I go ahead and use them. It will let me know if there is some code path where the proper variable is never set. This usually comes out through testing, especially during fuzzing so I guess it really only works because of my testing, otherwise it would come up during runtime...
lenkite 2 hours ago [-]
Say if you were designing a new language and wanted to include string formatting as a feature. Would you personally choose Python f-strings or C-style format strings or Rust-style formats ?
hmry 2 hours ago [-]
In terms of format string syntax, Rust is extremely similar to Python (and C++'s new std::format is also similar). So in that sense it seems Python-style "{name:fmt}" has won. Though the others don't support arbitrary expressions inside of the string.
On the other hand, you have formatting as an expression that evaluates to a string like f"..." in Python, vs formatting as a set of functions that take the same input format but do various things like printf/snprintf/write!/format!/std::print/std::format... Here it seems Python's approach had too many drawbacks, considering they just added formatted templates t"..." that don't evaluate to a string.
If I were to design a new language, I would use a Python-like "{expr:fmt}" syntax for formatting, but I would make it evaluate to some sort of FormatTemplate object that code can inspect.
f33d5173 10 minutes ago [-]
> Here it seems Python's approach had too many drawbacks, considering they just added formatted templates t"..." that don't evaluate to a string.
That's not a fair characterization at all, since the plan was always to add something like the t"" strings. Having a version that immediately evaluates to a string is convenient, and adds very little complexity either at the implementation level or conceptually.
pansa2 1 hours ago [-]
Can you get away with just f-strings? Python also has `string.format` for situations where the string needs to be built dynamically.
Are there languages which only have an f-string-like feature without a `string.format` equivalent?
jokoon 59 minutes ago [-]
I use them and I discovered a few that I did not know
Ah, these are great! f-strings are so powerful, but I can never remember the arcane little syntax. Definitely bookmarking this.
blueflow 4 hours ago [-]
I fail to see the purpose of f-strings if they end up as complex as printf formatting. Maybe use printf at this point?
ForceBru 2 hours ago [-]
I think the purpose is to put variables directly in the string literal instead of calling `printf`. Looking at an f-string immediately tells you where each value will be located in the output. `printf` requires you to read the format string, then look at the arguments, then count where a particular value will be printed.
lou1306 58 minutes ago [-]
`printf`/`str.format` are also prone to nasty failures: if you forget a variable (e.g., `str.format("{} {} {}", 0, 1)`), you only find out when you crash with an IndexError at runtime.
Hamuko 3 hours ago [-]
You don't really need to use any of these. Really the most useful one is f"{var=}" for us print() debuggers. But f"{var:#x}" is the same as f"{hex(var)}", so feel free to pick whatever you prefer.
f-strings put the value in the output string exactly where the value should be. Massive win for contextual awareness, no need to count ...3, 4, okay what's the position 4 value over on the right, does it match up?? And they use classic Python string formatting commands, except the = operator which makes them even better with a "name the variable, show its value in a concise way" option. What's not to like?
(And if you don't like them, uh...they're not mandatory. Just don't use them.)
https://peps.python.org/pep-0498/
> This PEP is driven by the desire to have a simpler way to format strings in Python.
I think f-strings have become the thing they were trying to replace and they are now more complicated than the old % interpolation.
I still like f-strings and use them a lot but if you look at the cheat sheet, they are no longer simple.
Most of the formatting options in the cheat sheet have always been available with f-strings. They are part of the Format Specification Mini Language (https://docs.python.org/3/library/string.html#format-specifi...) and both string.format and f-strings use the same spec. f-strings have some additional capabilities like inline expressions and debugging/logging with `=`.
Once a reader could be reasonably expected to consult reference material while working out what a print() is doing something has gone wrong. This is the programmer equivalent of wearing too much makeup.
Also, even though use in log messages is discouraged, I go ahead and use them. It will let me know if there is some code path where the proper variable is never set. This usually comes out through testing, especially during fuzzing so I guess it really only works because of my testing, otherwise it would come up during runtime...
On the other hand, you have formatting as an expression that evaluates to a string like f"..." in Python, vs formatting as a set of functions that take the same input format but do various things like printf/snprintf/write!/format!/std::print/std::format... Here it seems Python's approach had too many drawbacks, considering they just added formatted templates t"..." that don't evaluate to a string.
If I were to design a new language, I would use a Python-like "{expr:fmt}" syntax for formatting, but I would make it evaluate to some sort of FormatTemplate object that code can inspect.
That's not a fair characterization at all, since the plan was always to add something like the t"" strings. Having a version that immediately evaluates to a string is convenient, and adds very little complexity either at the implementation level or conceptually.
Are there languages which only have an f-string-like feature without a `string.format` equivalent?