ChatGPT解决这个技术问题 Extra ChatGPT

Python's many ways of string formatting — are the older ones (going to be) deprecated?

Python has at least six ways of formatting a string:

In [1]: world = "Earth"

# method 1a
In [2]: "Hello, %s" % world
Out[2]: 'Hello, Earth'

# method 1b
In [3]: "Hello, %(planet)s" % {"planet": world}
Out[3]: 'Hello, Earth'

# method 2a
In [4]: "Hello, {0}".format(world)
Out[4]: 'Hello, Earth'

# method 2b
In [5]: "Hello, {planet}".format(planet=world)
Out[5]: 'Hello, Earth'

# method 2c
In [6]: f"Hello, {world}"
Out[6]: 'Hello, Earth'

In [7]: from string import Template

# method 3
In [8]: Template("Hello, $planet").substitute(planet=world)
Out[8]: 'Hello, Earth'

A brief history of the different methods:

printf-style formatting has been around since Pythons infancy

The Template class was introduced in Python 2.4

The format method was introduced in Python 2.6

f-strings were introduced in Python 3.6

My questions are:

Is printf-style formatting deprecated or going to be deprecated?

In the Template class, is the substitute method deprecated or going to be deprecated? (I'm not talking about safe_substitute, which as I understand it offers unique capabilities)

Similar questions and why I think they're not duplicates:

Python string formatting: % vs. .format — treats only methods 1 and 2, and asks which one is better; my question is explicitly about deprecation in the light of the Zen of Python

String formatting options: pros and cons — treats only methods 1a and 1b in the question, 1 and 2 in the answer, and also nothing about deprecation

advanced string formatting vs template strings — mostly about methods 1 and 3, and doesn't address deprecation

String formatting expressions (Python) — answer mentions that the original '%' approach is planned to be deprecated. But what's the difference between planned to be deprecated, pending deprecation and actual deprecation? And the printf-style method doesn't raise even a PendingDeprecationWarning, so is this really going to be deprecated? This post is also quite old, so the information may be outdated.

See also

PEP 502: String Interpolation - Extended Discussion

String Formatter

Do I need to point out you forgot the Formatter class?

M
Mark Amery

The new .format() method is meant to replace the old % formatting syntax. The latter has been de-emphasised, (but not officially deprecated yet). The method documentation states as much:

This method of string formatting is the new standard in Python 3, and should be preferred to the % formatting described in String Formatting Operations in new code.

(Emphasis mine).

To maintain backwards compatibility and to make transition easier, the old format has been left in place for now. From the original PEP 3101 proposal:

Backwards Compatibility Backwards compatibility can be maintained by leaving the existing mechanisms in place. The new system does not collide with any of the method names of the existing string formatting techniques, so both systems can co-exist until it comes time to deprecate the older system.

Note the until it comes time to deprecate the older system; it hasn't been deprecated, but the new system is to be used whenever you write new code.

The new system has as an advantage that you can combine the tuple and dictionary approach of the old % formatter:

"{greeting}, {0}".format(world, greeting='Hello')

and is extensible through the object.__format__() hook used to handle formatting of individual values.

Note that the old system had % and the Template class, where the latter allows you to create subclasses that add or alter its behaviour. The new-style system has the Formatter class to fill the same niche.

Python 3 has further stepped away from deprecation, instead giving you warning in the printf-style String Formatting section:

Note: The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals or the str.format() interface helps avoid these errors. These alternatives also provide more powerful, flexible and extensible approaches to formatting text.

Python 3.6 also added formatted string literals, which in-line the expressions into the format strings. These are the fastest method of creating strings with interpolated values, and should be used instead of str.format() wherever you can use a literal.


And with Formatter you can create custom formats such as those that datetime objects use. Also, since .format is a function, you can use it to create callable lazy formatting more directly: eg, fmt = '{} - {}'.format; fmt(a, b)
I don't see how Template is related to % or to the old system. In particular the PEP you link states While there is some overlap between this proposal and string.Template, it is felt that each serves a distinct need, and that one does not obviate the other. In your answer one may be confused that Template formatting, being part of the old system, is deprecated too.
[...]should be preferred to the % formatting[...] this part has been removed from the documentation. docs.python.org/3/library/stdtypes.html#str.format
I think that this answer is currently misleading; the first passage quoted has been removed from the Python 3 docs, and it seems fairly clear to me that there's no remaining intent for a deprecation to take place. This answer still has historical value, but I'd be inclined to tweak the wording to avoid any suggestion that a deprecation is still in the cards, and to edit much of the first half of the answer to be in the past tense. I'll do so myself at some point if you don't object, but thought I'd comment first to give you a chance to make such changes yourself if you'd like to.
@MartijnPieters Fair enough. I stand by my criticism of this answer; I think you're wrong to read anything into the prose remaining in the Python 2 docs, and think there's definitely no prospect of a deprecation for reasons I outline in my answer and given by others in other answers here, but I won't edit to fundamentally change the meaning of your answer to one you disagree with.
j
jsbueno

The % operator for string formatting is not deprecated, and is not going to be removed - despite the other answers.
Every time the subject is raised on Python development list, there is strong controversy on which is better, but no controversy on whether to remove the classic way - it will stay. Despite being denoted on PEP 3101, Python 3.1 had come and gone, and % formatting is still around.

The statements for the keeping classic style are clear: it is simple, it is fast, it is quick to do for short things. Using the .format method is not always more readable - and barely anyone - even among the core developers, can use the full syntax provided by .format without having to look at the reference Even back in 2009, one had messages like this: http://mail.python.org/pipermail/python-dev/2009-October/092529.html - the subject had barely showed up in the lists since.

2016 update

In current Python development version (which will become Python 3.6) there is a third method of string interpolation, described on PEP-0498. It defines a new quote prefix f"" (besides the current u"", b"" and r"").

Prefixing a string by f will call a method on the string object at runtime, which will automatically interpolate variables from the current scope into the string:

>>> value = 80
>>> f'The value is {value}.'
'The value is 80.'

It's much nicer to allow types to implement their own __format__. For example, format(Decimal('0.1'), '.20f') vs '%.20f' % Decimal('0.1'). The latter coerces the Decimal to a float.
NB. I didn't argue that the old style is better in all respects - just that it is shorter and sometimes more readable (and sometimes not). Certainly the new way is much more flexible.
Is there a equivalent for f in Python 3?
The f-strings as used above are new feature in the language as of Python 3.6. It does not exist in previous versions and will raise a Syntax Error on those.
Also, in f-strings not only variables are interpolated, as written, but arbitrary expressions possibly including any arbitrary function and thus any arbitrary code.
M
Mark Amery

Looking at the older Python docs and PEP 3101 there was a statement that the % operator will be deprecated and removed from the language in the future. The following statement was in the Python docs for Python 3.0, 3.1, and 3.2:

Since str.format() is quite new, a lot of Python code still uses the % operator. However, because this old style of formatting will eventually be removed from the language, str.format() should generally be used.

If you go to the same section in Python 3.3 and 3.4 docs, you will see that statement has been removed. I also cannot find any other statement anywhere else in the documentation indicating that the operator will be deprecated or removed from the language. It's also important to note that PEP3101 has not been modified in over two and a half years (Fri, 30 Sep 2011).

Update

PEP461 Adding % formatting to bytes and bytearray is accepted and should be part of Python 3.5 or 3.6. It's another sign that the % operator is alive and kicking.


M
Mark Amery

While there are various indications in the docs that .format and f-strings are superior to % strings, there's no surviving plan to ever deprecate the latter.

In commit Issue #14123: Explicitly mention that old style % string formatting has caveats but is not going away any time soon., inspired by issue Indicate that there are no current plans to deprecate printf-style formatting, the docs on %-formatting were edited to contain this phrase:

As the new string-formatting syntax is more flexible and handles tuples and dictionaries naturally, it is recommended for new code. However, there are no current plans to deprecate printf-style formatting.

(Emphasis mine.)

This phrase was removed later, in commit Close #4966: revamp the sequence docs in order to better explain the state of modern Python. This might seem like a sign that a plan to deprecate % formatting was back on the cards... but diving into the bug tracker reveals that the intent was the opposite. On the bug tracker, the author of the commit characterises the change like this:

changed the prose that describes the relationship between printf-style formatting and the str.format method (deliberately removing the implication that the former is any real danger of disappearing - it's simply not practical for us to seriously contemplate killing it off)

In other words, we've had two consecutive changes to the %-formatting docs intended to explicitly emphasise that it will not be deprecated, let alone removed. The docs remain opinionated on the relative merits of different kinds of string formatting, but they're also clear the %-formatting isn't going to get deprecated or removed.

What's more, the most recent change to that paragraph, in March 2017, changed it from this...

The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals or the str.format interface helps avoid these errors. These alternatives also provide more powerful, flexible and extensible approaches to formatting text.

... to this:

The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals, the str.format interface, or template strings may help avoid these errors. Each of these alternatives provides their own trade-offs and benefits of simplicity, flexibility, and/or extensibility.

Notice the change from "helps avoid" to "may help avoid", and how the clear recommendation of .format and f-strings has been replaced by fluffy, equivocal prose about how each style "provides their own trade-offs and benefits". That is, not only is a formal deprecation no longer on the cards, but the current docs are openly acknowledging that % formatting at least has some "benefits" over the other approaches.

I'd infer from all this that the movement to deprecate or remove % formatting has not only faltered, but been defeated thoroughly and permanently.


The fluffy language change was added to placate the Mercurial maintainers (among others) that didn’t want to see Mercurial left behind with a codebase too large to eradicate the use of %. Now that the ‘no large scale code mods’ policy has been scrapped, their objections are fading too. In the long run, maintaining both forms with no benefits remaining for % at some point the printf syntax will be removed anyway. We just don’t know when yet, and so the language was worth toning down.
@MartijnPieters Interesting. It sounds like you have a great deal of knowledge about this decision that I lack. For what it's worth, I think a well-referenced answer from you outlining these points (either as a new answer, or an edit to your existing one) would have value.
L
Lev Levitsky

Guido's latest position on this seems to be indicated here:

What’s New In Python 3.0

PEP 3101: A New Approach To String Formatting A new system for built-in string formatting operations replaces the % string formatting operator. (However, the % operator is still supported; it will be deprecated in Python 3.1 and removed from the language at some later time.) Read PEP 3101 for the full scoop.

And the PEP3101 itself, which has the last modified dating back to (Fri, 30 Sep 2011), so no progress as of late on that one, I suppose.