Hacker News new | past | comments | ask | show | jobs | submit login

F-strings have appeared 2 versions ago. All in all, the feedback we have has been overwhelmingly positive, including on maintenance and readability.



I second this. F-strings make string formatting so much more concise. I'm excited about the walrus operator for the same reason.


Not just more concise; less error prone.

A reasonably large number of the bugs I encounter relate to the order or number of formatting arguments not matching the slots in the format string. It's pretty hard to make that kind of mistake with an fstring.


f-strings allow mutation ?

mutation is tricky, a whole field of programming language research is built on avoiding mutation


I love f-strings. I just wish tools like pylint would shut up when I pass f-strings to the logging module. I as the developer understand and accept the extra nanosecond of processor time to parse the string that might not be logged anywhere!


It's not just performance!

Using percent formatting is superior in many ways:

- errors that occur in formatting a message will be logged instead of raising an exception into your application

- error reporting services like Sentry can properly aggregate events

- interpolation won't occur if you don't have the logging level enabled

- it's recommend by the Python docs: https://docs.python.org/3/howto/logging-cookbook.html#use-of...


It's not always a nanosecond, some string representations can take a while to create. In poorly coded Django models they could involve a trip to the database.


    if logger.isEnabledFor(logging.DEBUG):
        logger.debug(f'{expensive_func()}')


I hope that’s a joke, because that is a verbose and ridiculous way of duplicating the work that the logging module does, while also making the code less readable and maintainable!


That’s how you defer an expensive function. The fstring part is the joke.


Disable it in pylintrc. Pylint is unusable without a good config file anyway.


Ideally the defaults should be sensible. I have found they mostly are, except the f-string one.


For something as finely tuned as pylint, my sensible default and your would never be the same.

I don't want it to scream on a missing docstring for every single thing. I do want to be able to use a, b and x as variables. No, this root var is not a constant, don't ask me for uppercase. Etc.


on the contrary, i've seen code slow down by 50% due to a log.debug() that wasn't even emitted in prod. should've seen my face when i saw the pyspy flamechart.


pylint still sucks at partial function definitions. It wants to name anything that exists in the module scope that isn't an explicit function definition with CAPS_LOCK_MODE.

    $ pylint pylint_sucks_at_partials.py 
    ************* Module pylint_sucks_at_partials
    pylint_sucks_at_partials.py:7:0: C0103: Constant name 
    "add5" doesn't conform to UPPER_CASE naming style 
    (invalid-name)
The program in question:

    #!/usr/bin/env python
    """ proving pylint still sucks at partials """
    from functools import partial
    from operator import add
    
    
    add5 = partial(add, 5)
    
    
    if __name__ == '__main__':
        import sys
        print(add5(int(sys.argv[1])))


F-string are great and should have been in the language since the beginning. Many other languages had with their own version of them since version 0. What I don't understand is why Python needs a special string type when other languages can interpolate normal strings (Ruby, Elixir, JavaScript.)


f-strings need a prefix so old strings can keep working the same way.

If `print("{x}")` printed "{x}" in Python 3.5, it shouldn't print something else in a newer version. But `print(f"{x}")` was a syntax error before f-strings, so no code is broken by giving it a meaning.

JavaScript can't interpolate ordinary strings either, for the same reason. You need to use backticks (``).


You're correct about JavaScript. I forgot about the backticks.

Thank you for the explanation of the f-strings. I'm pretty sure that migrating old strings to "\{x\}" could be automated but we can't force everybody to migrate their code. There is probably no other way than the one they followed.


"\{x\}" includes the backslashes into the string literally. So even if that worked for f-strings it would change the meaning for older Python versions. Requiring people to update common old code is also just something to avoid unless necessary.

The correct way to escape braces in f-strings is with double braces, so f"{{x}}". This is consistent with the way str.format works. f-string syntax is very similar to str.format syntax in general.


It's also just safer. You want your default string type to have as few gotchas about what can be put in it as possible.


Shells do it with "" and ''. Unfortunately Py and Js decided to allow both for regular strings, so there is not such an easy way to delineate them.


Because explicit is better than implicit.


...but every addition to make them more powerful and feature-rich is one more step in the direction of blurring the lines between what's code and what isn't, since more and more things that are supposed to be code will be expressed in ways that aren't code at all but fed to an interpreter inside the interpreter. And with every release, the language specification that I'm having to hold in my head when dealing with other people's code grows more and more complex while the cost-benefit calculation around the additional complexity shows diminishing returns.

It kind of goes to the question: When is a language "finished"?


there's a difference between stability and stagnation and IMHO Python gets it.

finished is dead, to put it less mildly.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: