Hi, So I'm in favour of using f-strings, but agree that there are places where they are not appropriate.
I am also against bulk updates in this case as mentioned in my previous comment <https://github.com/django/django/pull/12650#issuecomment-607707454>. I don't think we should exclude replacing .format() with f-strings on a case-by-case basis, however, where performance is a concern. Thanks for your initial documentation, Carlton. Am wondering whether we should be more explicit about the pros and cons of each to help people make the correct decision? Here are my thoughts: %-formatting: + Simple to use printf-style familiar to all. + Default (can be changed <https://docs.python.org/3/howto/logging-cookbook.html#formatting-styles>) style used internally by the logging module, e.g. logging.info('Message with %s.', value) − Much less flexibility for formatting, see pyformat.info. ``.format()``: + Useful for interpolating a stored template string, e.g. from a database, which isn't possible with f-strings. − Worst performance due to method call. − Much more verbose, makes code less readable. f-strings: + Better performance than other methods due to dedicated FORMAT_VALUE <https://bugs.python.org/issue25483> opcode. + Allows for embedding more complex expressions, e.g. f'Hello {user.get_full_name()}' + Much more concise, makes code more readable. − Cannot be used if string must be translated. − Complex expressions can get out of control. A sensible balance needs to be struck. Regarding performance, here are some simple numbers: python -m timeit -s 'x="test"' 'f"{x}"' 20000000 loops, best of 5: 11.8 nsec per loop $ python -m timeit -s 'x="test"' '"%s" % x' 10000000 loops, best of 5: 39.1 nsec per loop $ python -m timeit -s 'x="test"' '"{}".format(x)' 5000000 loops, best of 5: 76.1 nsec per loop I think it is probably also worth updating the documentation added in this commit <https://github.com/django/django/commit/c3437f734d03d93f798151f712064394652cabed>. It isn't that xgettext doesn't support f-strings... It does: $ echo "_('Hello %s') % user.username" | xgettext --language=python --omit-header --output=- - #: standard input:1 #, python-format msgid "Hello %s" msgstr "" $ echo "_('Hello {}').format(user.username)" | xgettext --language=python --omit-header --output=- - #: standard input:1 msgid "Hello {}" msgstr "" $ echo "_('Hello {name}').format(name=user.username)" | xgettext --language=python --omit-header --output=- - #: standard input:1 #, python-brace-format msgid "Hello {name}" msgstr "" $ echo "_(f'Hello {user.username}')" | xgettext --language=python --omit-header --output=- - #: standard input:1 #, python-brace-format msgid "Hello {user.username}" msgstr "" $ echo "_(f'Hello {user.get_full_name()}')" | xgettext --language=python --omit-header --output=- - #: standard input:1 msgid "Hello {user.get_full_name()}" msgstr "" It is actually that Python doesn't support modifying the template string prior to interpolating the values which is the requirement for injecting the translated string. PEP 498 <https://www.python.org/dev/peps/pep-0498/> makes no explicit mention of this. PEP 501 <https://www.python.org/dev/peps/pep-0501/> was initially looking at solving the problem but was deemed a poor fit and was also deferred. Kind regards, Nick On Tuesday, 21 July 2020 at 08:28:54 UTC+1 Mariusz Felisiak wrote: > Hi y'all, > > I will not stand against f-strings, I think we can allow them. My main > concerns is readability. f-strings are powerful and it's quite common that > they are used with functions calls and complex formatting which makes code > hard to understand and maintain, *"With great power comes great > responsibility" ...* > > I'm strongly against any bulk updates to conform to this style. This > will just create unnecessary noise in the history, I know that there are > tools, please don't start this discussion again :) > > I would also be in favor of keeping only %-formatting and f-strings in > Coding style docs. I don't see any reason to use also `format()` in a new > code. > > Best, > Mariusz > -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/ceba9695-9d21-436f-84b5-53381aa3ea15n%40googlegroups.com.